考虑以下声明:
const [stateObject, setObjectState] = useState({
firstKey: '',
secondKey: '',
});
以下代码片段是否正确?
一(
setObjectState((prevState) => ({
...prevState,
secondKey: 'value',
}));
二(
setObjectState({
...stateObject,
secondKey: 'value',
}));
我确定 A( 是正确的,但有必要吗?B( 似乎没问题,但由于 setObjectState 是一个异步函数,stateObject 可能没有最新的值。
关于 A 的情况,我发现的一个有用的事情是,您可以使用此方法从子组件更新状态,同时只传递一个 prop 用于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>
)
}
按下按钮时,您应该会看到状态已更新,同时还保留其初始值。至于两者之间的区别,没有太大,因为他们都完成了同样的事情。
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("");