从 React 的 useState 钩子改变状态 [英] Mutating state from React's useState hook

查看:20
本文介绍了从 React 的 useState 钩子改变状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

考虑以下代码:

const [values, setValues] = useState({})//doSomething 可以在每次渲染时调用一次或多次const doSomething = (name, value) =>{值[名称] = 值setValues({ ...values })}

注意值的变化.由于每次渲染可以多次调用 doSomething,由于 setState 的异步属性,这样做是行不通的:

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

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

解决方案

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

const { useState } = React;功能应用(){const [values, setValues] = useState({});const doSomething = (name, value) =>{值[名称] = 值;设置值(值);};返回 (<div onClick={() =>doSomething(Math.random(), Math.random())}>{JSON.stringify(values)}

);}ReactDOM.render(, document.getElementById("root"));

<script src="https://unpkg.com/react@16/umd/react.development.js"><;/脚本><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;功能应用(){const [values, setValues] = useState({});const doSomething = (name, value) =>{setValues(values => ({ ...values, [name]: value }));};返回 (<div onClick={() =>doSomething(Math.random(), Math.random())}>{JSON.stringify(values)}

);}ReactDOM.render(, document.getElementById("root"));

<script src="https://unpkg.com/react@16/umd/react.development.js"><;/脚本><script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script><div id="root"></div>

Is it, and why is it a bad idea to mutate a state from React's new useState hook? I found no info on the topic.

Consider following code:

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

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

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

Note the mutation of values. Since doSomething can be called more than once per render, doing this would not work because of the async properties of setState:

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

Is the approach of mutating values directly the correct one in this case?

解决方案

You should never mutate state directly as it might not even cause a re-render if you update the state with the same object reference.

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>

You can give a function as first argument to setValues just like you are used to in the class component setState, and that function in turn will get the correct state as argument, and what is returned will be the new state.

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>

这篇关于从 React 的 useState 钩子改变状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆