gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 00:59:57 25 4
gpt4 key购买 nike

我正在尝试创建一个具有“静态”模式的输入组件。在此模式下,输入将替换为包含输入值的范围。在这个问题中,我使用范围输入。

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 返回函数现在无法正确读取输入,因为它实际上已卸载。我认为在 useEffect 中使用返回函数会导致一个函数在组件卸载之前运行。我做错了什么?

最佳答案

当然,你无法访问 document.getElementById(inputID).value如果<input>元素未安装 - 它不存在!即使它确实如此,你也不会想以这种方式解读它的值(value)。这是一种非常非 React 的做事方式。 React 组件应该在状态和属性中拥有它们所需的一切 - 如果您发现自己直接查询或对 DOM 进行操作,那么您(几乎总是)走上了一条黑暗之路。

相反,您想要的是 controlled component .

受控组件不依赖 DOM 来存储“值”之类的任何内容。相反,该组件仅显示 React 状态中的任何值并提供方便的事件 Hook 。

我强烈建议您阅读我链接的文档,看看您是否可以自己找出实现方案。毕竟这是最好的学习方式!但如果您仍然无法弄清楚,我会回来用一个基本的工作示例编辑我的答案。

编辑:这是一个简单的工作演示,其中包含一些评论。

https://stackblitz.com/edit/controlled-input-demo?file=index.js

请注意,它实际上非常简单! <App>跟踪状态中的 slider 值,而 <RangeInput>只需将该值用作 prop,并提供一个事件处理程序以将其更新回 <App><RangeSlider>可以跟踪其自己的“编辑模式”值,因为其他组件可能不需要访问它(但如果您愿意,您可以“提升”该状态!)您甚至不需要 useEffect()在这里!

关于javascript - 我无法使 useEffect 在条件渲染上正确读取输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56177029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com