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

时间:2019-12-26 14:46:57

标签: reactjs react-hooks

使用挂钩,如果我用与setState相同的值调用state,它将重新呈现该组件吗?

如果是,如何避免这种情况?

例如

const [state, setState] = useState(foo)

...
// any where in the code
setState(foo)

考虑到foo可以是任何东西,例如{}trueprops.bar或组件外部的变量(常量)。

2 个答案:

答案 0 :(得分:2)

如果调用具有相同值的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>);
};

您会注意到,即使单击按钮,因为值未更改。它没有重新渲染组件。如果更改用于调用setState的参数,它将重新呈现组件。


  

这是您推荐的Code Sample

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

答案 1 :(得分:0)

这是与js语法相关的问题,就像===操作一样。

let times = 0
const init = {name: 'Bob'}
function App() {
  const [state, setState] = useState(init)
  function modify() {
    setState({name: 'Bob'})
  }
  function modify2() {
    setState(init)
  }
  times ++
  return (
    <div className="App">
      <p>{ times }</p>
      <button onClick={modify}>Same Value Will Rerender</button>
      <button onClick={modify2}>Same Reference Never Rerender</button>
    </div>
  );
}
  

这里是Code Sandbox

您可以重写包装方法:

let times = 0
const init = {name: 'Bob'}
function App() {
  const [state, setState] = useState(init)
  function modify3() {
    setState2({ name: 'Bob' })
  }
  function setState2(value) {
    if (value.name === state.name) {
      return
    }
    setState(value)
  }
  times ++
  return (
    <div className="App">
      <p>{ times }</p>
      <button onClick={modify3}>Same Value Will Not Rerender Yet</button>
    </div>
  );
}