简体   繁体   English

使用嵌套字段/对象时,使用React setState挂钩在更新后状态消失

[英]State disappears after update using React setState hook when using nested fields/object

In my example below, when I update a certain field, the other field in my state object disappears/unset and I get a warning about inputs becoming uncontrolled. 在下面的示例中,当我更新某个字段时,状态对象中的另一个字段消失/未设置,并且我收到关于输入变得不受控制的警告。 Example below: 下面的例子:

 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> 

As the React docs state: 如React docs所述:

However, unlike this.setState in a class, updating a state variable always replaces it instead of merging it. 但是,与this.setState中的this.setState不同,更新状态变量总是替换它而不是合并它。

So using setUser does not do a shallow merge of the object, instead it replaces the state with the entire object, which causes the other field to disappear. 因此,使用setUser不会对对象进行浅层合并,而是将状态替换为整个对象,这会导致其他字段消失。 You could use Object.assign or spread ( ... ) operator to merge the objects together when doing setUser . 在执行setUser时,可以使用Object.assign或spread( ... )运算符将对象合并在一起。

 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> 

Alternatively, create a custom hook called useMergeState to help you do merging automatically like in the usual setState . 或者,创建一个名为useMergeState的自定义钩子,以帮助您像通常的setState一样自动进行合并。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM