使用钩子设置具有相同值的状态会导致重新渲染吗?

Ven*_*sky 5 reactjs react-hooks

使用钩子,如果我setState使用与 相同的值调用state,它会重新渲染组件吗?

如果是,我怎样才能避免这种情况?

例如

const [state, setState] = useState(foo)

...
// any where in the code
setState(foo)
Run Code Online (Sandbox Code Playgroud)

考虑到foo可以是任何事物,比如{}trueprops.bar或从所述部件(常数)的出侧可变。

Vla*_*nin 16

只是总结一下

如果您的状态是原始值(数字、字符串、布尔值...),则使用 setState 挂钩设置相同的值不会触发重新渲染。如果您的状态是对象或数组,那么它的行为会有所不同。

https://overreacted.io/how-are-function-components-
Different-from-classes/ https://dmitripavlutin.com/value-vs-reference-javascript/

  • 我认为我们不应该区分。如果它是相同(相同引用)的对象或数组,无论是因为它是在渲染函数之外声明的还是通过“useMemo”声明的,它都不会触发重新渲染。所以我们可以简单地说“如果`Object.is(prevValue, newValue)`返回`true`,它就不会重新渲染”。 (3认同)

Sid*_*era 8

如果您setState使用相同的值调用,它不会重新渲染组件。

试试这个:

import React, { useState, useEffect } from "react";

const foo = { foo: 'bar' };

export default ({ name }) => {
  const [state, setState] = useState(foo);
  console.log("rendered!");
  useEffect(() => {
    setState(foo);
    console.log("state reset!");
  });

  const handleClick = () => {
    console.log("handleClick!");
    setState(foo);
    // setState({ ...foo, bar : 'baz' });
  }

  return (<div>
  <h1>Hello {name}!</h1>
  <button onClick={handleClick}>Click Me</button>
  </div>);
};
Run Code Online (Sandbox Code Playgroud)

您会注意到,即使单击该按钮,该值也没有改变。它不是重新渲染组件。如果您更改您调用的参数,setState它将重新渲染组件。


这是您参考的代码示例

尝试在方法中注释第一个setState并取消注释第二个handleClick以查看差异。

  • 此处为上面的示例添加注释。如果您使用像这样的文字对象“setState({ foo: 'bar' })”,即使该对象看起来相同,它也总是会重新渲染。这是因为每次创建文字对象时,它都被认为与旧对象不同。就像当你比较两个文字对象 `{a: 1} === {a: 1}` 时它返回 `false` (7认同)
  • 只是想添加另一个参考来确认这一点。React Hooks 文档提到:“如果您的更新函数返回与当前状态完全相同的值,则将完全跳过后续重新渲染。” https://reactjs.org/docs/hooks-reference.html#function-updates (3认同)