考虑以下声明:
const [stateObject, setObjectState] = useState({
firstKey: '',
secondKey: '',
});
以下代码片段都正确吗?
A)
setObjectState((prevState) => ({
...prevState,
secondKey: 'value',
}));
B)
setObjectState({
...stateObject,
secondKey: 'value',
}));
我确定A)是正确的,但是有必要吗? B)似乎还可以,但是由于setObjectState是一个异步函数,因此stateObject可能没有最新值。
答案 0 :(得分:0)
关于A的情况,我发现一个有用的事情是,您可以使用此方法从子组件更新状态,而只传递setObjectState
的单个属性。例如,假设您的父组件的状态要从子组件更新。
父项:
import React, {useState} from 'react';
import ChildComponent from './ChildComponent';
export const ParentComponent = () => {
const [parentState, setParentState] = useState({
otherValue: null,
pressed: false,
});
return (
<ChildComponent setParentState={setParentState} />
)
}
子组件:
import React from 'react';
export const ChildComponent = (props) => {
const callback = () => {
props.setParentState((prevState) => ({
...prevState
pressed: true,
}))
}
return (
<button onClick={callback}>test button<button>
)
}
按下按钮时,您应该希望看到状态已更新,同时还保留其初始值。至于两者之间的区别,两者都完成相同的事情。
答案 1 :(得分:0)
A将始终为您提供更新的值。 B 可能是正确的,但不一定。让我举个例子:
const Example = props => {
const [counter, setCounter] = useState(0);
useEffect(() => {
// 0 + 1
// In this first case the passed value would be the same as using the callback.
// This is because in this cycle nothing has updated counter before this point.
setCounter(counter + 1);
// 1 + 1
// Thanks to the callback we can get the current value
// which after the previous iexample is 1.
setCounter(latest_value => latest_value + 1);
// 0 + 1
// In this case the value will be undesired as it is using the initial
// counter value which was 0.
setCounter(counter + 1);
}, []);
return null;
};
当新值取决于更新后的值时,请使用回调,否则您可以简单地传递新值。
const Example = props => {
const [hero, setHero] = useState('Spiderman');
useEffect(() => {
// Fine to set the value directly as
// the new value does not depend on the previous one.
setHero('Batman');
// Using the callback here is not necessary.
setHero(previous_hero => 'Superman');
}, []);
return null;
};
此外,在示例中,您给出使用两个不同的状态可能更好:
const [firstKey, setFirstKey] = useState("");
const [secondKey, setSecondKey] = useState("");