reactjs - useState 钩子返回的更新函数不更新值
问题描述
一些非常奇怪的事情正在发生。我有一个状态值,定义如下:
const [heightField, setHeightField] = useState<FormField<string>>(new FormField<string>(""));
我还定义了一个与该状态值相关的 useEffect 钩子,它的定义如下:
useEffect(() => console.log('heightfield changed, hi from the useEffect hook!'), [heightField]);
此 heightField 值在文本字段中引用,如下所示:
<TextField
required
label="Height (cms)"
margin="normal"
variant="outlined"
type="number"
value={heightField.value}
onChange={(event) => {
setHeightField(new FormField<string>(event.target.value))
}}
error={heightField.error}
helperText={heightField.errorMessage}
/>
现在,当我在文本字段中输入文本时,heightField 值会相应更新,并且 useEffect 挂钩也会被触发。
但是,当从另一个函数更新 heightField 值时,它的值不会更新,也不会触发 useEffect 挂钩。坦率地说,我不明白为什么会发生这种行为。功能如下:
const validateHeight = (heightField: FormField<string>) => {
const heightNumber = parseInt(heightField.value);
let error = false;
let errorMessage = "";
if (!heightNumber) {
error = true;
errorMessage = "Wrong number, please verify.";
}
else if (heightNumber < 0 || heightNumber > 220) {
error = true;
errorMessage = "Please verify the height";
}
const nHeightField = new FormField<string>(heightField.value, error, errorMessage);
setHeightField(nHeightField);
}
当点击表单的提交按钮时调用此函数,调用时不会触发 useEffect 钩子,也不会相应更新 heightField 值
有什么我想念的吗?为什么在使用新对象调用更新函数时不更新此值?
解决方案
从您在问题和评论中告诉我们的内容来看,state
对象引用似乎保持不变,即使它的属性发生了变化。尝试通过执行以下操作来创建该对象的副本:
setState({...heightField});
或者,如果您在更新之前需要以前的state
内容:
setState((prevState) => {
const aux = {...prevState};
aux.someProp = someOtherValue;
return aux;
});
如果你的 state 是一个对象,并且对象引用在两次渲染之间保持不变,React 会认为它没有改变并且不会更新它。因为它只比较值。如果是 anumber
或 a string
,它将按值进行比较,但如果是 a object
,它将按引用进行比较,并且不会深入object
研究属性。
推荐阅读
- rust - 如何将上传的文件保存到文件夹?
- angular - 关闭 refCount 的 rxjs shareReplay 在第一个下游订阅者之前不会订阅源
- r - 将数据帧列表取消列出到一个具有更改结构的数据帧
- visual-studio - 在 Visual Studio 中,如何将文件的不同版本发布到 Mac 和 PC (.Net Core)
- python - 打开并立即使用没有上下文管理器的文件是否危险?
- mule - 高安全性问题影响-Mule-runtimes-of-all-supported-versions-March-19th-2020
- flutter - 列中的 Flutter 2 Streambuilders
- ansible - Ansible - 名称中带有 host_vars 和字符串的动态变量
- awk - 如果条件存在,如何删除部分字符串
- excel - ListRows.Add 不会使相邻列中的数据下移