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

时间:2018-11-25 20:53:14

标签: javascript reactjs react-hooks

在下面的示例中,当我更新某个字段时,状态对象中的另一个字段消失/未设置,并且我收到有关输入变得不受控制的警告。下面的示例:

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>

1 个答案:

答案 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一样自动合并。