在下面的示例中,当我更新某个字段时,状态对象中的另一个字段消失/未设置,并且我收到有关输入变得不受控制的警告。下面的示例:
const {useState} = React;
const App = () => {
const [user, setUser] = useState({
firstName: 'Mary',
lastName: 'Poppins',
});
return (
<div>
First Name: <input value={user.firstName} onChange={e => {
setUser({firstName: e.target.value});
}} />
<br />
Last Name: <input value={user.lastName} onChange={e => {
setUser({lastName: e.target.value});
}} />
<br />
{JSON.stringify(user, null, 2)}
</div>
);
};
ReactDOM.render(<App />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
答案 0 :(得分:2)
如React docs所述:
但是,与类中的
this.setState
不同,更新状态变量总是代替它而不是合并它。
因此,使用setUser
不会对对象进行浅表合并,而是将状态替换为整个对象,这会导致其他字段消失。进行Object.assign
时,可以使用...
或传播(setUser
)运算符将对象合并在一起。
const {useState} = React;
const App = () => {
const [user, setUser] = useState({
firstName: 'Mary',
lastName: 'Poppins',
});
return (
<div>
First Name: <input value={user.firstName} onChange={e => {
setUser(Object.assign({}, user, {firstName: e.target.value}));
}} />
<br />
Last Name: <input value={user.lastName} onChange={e => {
setUser(Object.assign({}, user, {lastName: e.target.value}));
}} />
<br />
{JSON.stringify(user, null, 2)}
</div>
);
};
ReactDOM.render(<App />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
或者,创建一个名为useMergeState
的自定义挂钩,以帮助您像通常的setState
一样自动合并。