为了账号安全,请及时绑定邮箱和手机立即绑定

我无法在条件渲染时使 useEffect 正确读取输入

我无法在条件渲染时使 useEffect 正确读取输入

我正在尝试创建一个具有“静态”模式的输入组件。在这种模式下,输入被包含输入值的跨度替换。在这个问题中,我使用范围输入。import React from 'react';import ReactDOM from 'react-dom';const { useState, useEffect, } = React;const RangeInput = ({  inputID, min, max, defaultValue, children,}) => {  const [valueAfterStaticChange, setValueAfterStaticChange] = useState(    defaultValue  );  const [isStatic, setIsStatic] = useState(false);  useEffect(    () => () => {      // do this before component unmounts and when 'isStatic' changes,      // but only when 'isStatic' is true      isStatic        || setValueAfterStaticChange(document.getElementById(inputID).value);    },    [isStatic]  );  return (    <div>      <label htmlFor={inputID}>{children}</label>      <span style={{ display: isStatic || 'none', }}>        {valueAfterStaticChange}      </span>      <input        type="range"        min={min}        max={max}        defaultValue={valueAfterStaticChange}        id={inputID}        style={{ display: isStatic && 'none', }}      />      <button        onClick={() => {          setIsStatic(!isStatic);        }}      >        Toggle Static      </button>    </div>  );};ReactDOM.render(  <RangeInput inputID="myID" min={0} max={100} defaultValue={50}>    My Range Input  </RangeInput>,  document.getElementById('root'));上面的代码有效。但它用于display: none模拟“无渲染”。我认为我可以通过以下逻辑完成实际卸载:// all unchanged until...   return (    <div>      <label htmlFor={inputID}>{children}</label>      {isStatic ? (        <span>{valueAfterStaticChange}</span>      ) : (        <input          type="range"          min={min}          max={max}          defaultValue={valueAfterStaticChange}          id={inputID}        />      )}      <button        onClick={() => {          setIsStatic(!isStatic);        }}      >        Toggle Static      </button>    </div>  );};不知何故,我的useEffect返回函数将无法正确读取输入,因为它实际上已卸载。我认为使用返回函数 inuseEffect会导致一个函数会在组件卸载之前运行。我究竟做错了什么?
查看完整描述

2 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

除非在卸载时有理由获取该值,否则您似乎可以在该值发生变化时对其进行跟踪。这样你就根本不需要useEffect:


const RangeInput = ({ inputID, min, max, defaultValue, children }) => {

  const [value, setValue] = useState(defaultValue); // <-- keep track of value

  const [isStatic, setIsStatic] = useState(false);


  return (

    <div>

      <label htmlFor={inputID}>{children}</label>

      {isStatic ? (

        <span>{value}</span>

      ) : (

        <input

          type="range"

          min={min}

          max={max}

          defaultValue={value}

          onChange={e => setValue(e.target.value)} // <-- Set value onChange

          id={inputID}

        />

      )}

      <button

        onClick={() => {

          setIsStatic(!isStatic);

        }}

      >

        Toggle Static

      </button>

    </div>

  );

};


查看完整回答
反对 回复 2021-06-03
  • 2 回答
  • 0 关注
  • 223 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信