javascript - 从 React 的 useState 钩子(Hook)改变状态

标签 javascript reactjs react-hooks

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

考虑以下代码:

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 })
}

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

最佳答案

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

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>

关于javascript - 从 React 的 useState 钩子(Hook)改变状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55178507/

相关文章:

javascript - 如何将值从输入字段传递给 JavaScript 闭包

javascript - 如何过滤表格?

reactjs - Material-UI:一个组件正在将 SwitchBase 不受控制的检查状态更改为受控

reactjs - TypeScript:将函数参数值限制为动态变量中的数组值

javascript - W3 学校 cookie 的删除 cookie 按钮

javascript - 在 React.js 中更新组件 onScroll 的样式

javascript - 如何在 Click React 上创建组件

react-native - 自定义单选按钮在 native react 中不起作用

reactjs - 映射对象数组状态时如何重新渲染 react 组件

javascript - AWS S3 : MaxPostPreDataLengthExceeded Your POST request fields preceeding the upload file was too large