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

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

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

蝴蝶不菲 2019-04-18 10:15:25
我正在尝试使用“静态”模式创建输入组件。在此模式下,输入将被包含输入值的范围替换。在这个问题中,我使用范围输入。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返回函数在它实际卸载时不会正确读取输入。我认为使用return函数useEffect会导致函数在组件卸载之前运行。我究竟做错了什么?
查看完整描述

2 回答

?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

除非在卸载时有理由获得该值,否则您可能只是在更改时跟踪该值。那样你根本不需要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>
  );};


查看完整回答
反对 回复 2019-05-17
  • 2 回答
  • 0 关注
  • 1337 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号