从React的useState挂钩中更改状态

时间:2019-03-15 08:34:37

标签: javascript reactjs react-hooks

是的,为什么从React的新useState挂钩中改变状态是一个坏主意?我没有找到有关该主题的信息。

考虑以下代码:

const [values, setValues] = useState({})

// doSomething can be called once, or multiple times per render

const doSomething = (name, value) => {
  values[name] = value
  setValues({ ...values })
}

请注意值的突变。由于每个渲染可以多次调用doSomething,因此由于setState的异步属性而无法执行此操作:

const doSomething = (name, value) => {
  setValues({ ...values, [name]: value })
}

在这种情况下,直接改变值的方法是否正确?

1 个答案:

答案 0 :(得分:3)

永远不要直接更改状态,因为如果使用相同的对象引用更新状态,甚至可能不会导致重新渲染。

const { useState } = React;

function App() {
  const [values, setValues] = useState({});

  const doSomething = (name, value) => {
    values[name] = value;
    setValues(values);
  };

  return (
    <div onClick={() => doSomething(Math.random(), Math.random())}>
      {JSON.stringify(values)}
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

您可以给函数setValues作为第一个参数,就像您在类组件setState中惯用的那样,然后该函数将获得正确的状态作为参数,并返回什么将是新状态。

const doSomething = (name, value) => {
  setValues(values => ({ ...values, [name]: value }))
}

const { useState } = React;

function App() {
  const [values, setValues] = useState({});

  const doSomething = (name, value) => {
    setValues(values => ({ ...values, [name]: value }));
  };

  return (
    <div onClick={() => doSomething(Math.random(), Math.random())}>
      {JSON.stringify(values)}
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>