正在发生非常奇怪的事情。我有一个状态值,定义如下:
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值也不会相应更新
我缺少什么吗?为什么在使用新对象调用更新功能时不更新此值?
答案 0 :(得分:1)
从您在问题和评论中告诉我们的内容来看,state
对象引用似乎保持不变,即使其属性已更改。尝试通过执行以下操作来创建该对象的副本:
setState({...heightField});
或者如果您需要上一个state
中的内容,然后再进行更新:
setState((prevState) => {
const aux = {...prevState};
aux.someProp = someOtherValue;
return aux;
});
如果您的状态是一个对象,并且在两次渲染之间对象引用保持不变,React会认为它没有改变并且不会更新。因为它仅比较值。如果它是number
或string
,则将按值进行比较,但如果是object
,则将按引用进行比较,并且不会深入研究object
属性。>