我正在尝试创建一个具有“静态”模式的输入组件。在这种模式下,输入被包含输入值的跨度替换。在这个问题中,我使用范围输入。
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会导致一个函数会在组件卸载之前运行。我究竟做错了什么?
手掌心
相关分类