如果 useEffect 侦听非状态值,那么依赖项数组中包含非状态值会产生什么效果?

una*_*der 3 javascript reactjs

每次Comp重新渲染,rand都会有不同的值。会触发吗useEffect

function Comp({}) {
  const rand = Math.random();

  useEffect(() => {
    // do stuff
  }, [rand])
}
Run Code Online (Sandbox Code Playgroud)

You*_*mar 11

任何变量都可以进入依赖数组,state也可以不进入。只要它在数组中并且发生变化,useEffect的回调就会重新执行。

现在,如何useEffect注意到这种变化?嗯,每当组件渲染时它都会进行比较。并且只有state使用 a 进行更改setState才能触发渲染(这里不讨论渲染,因为这里有父组件渲染)。

如果你已经理解了这个机制,你可以停在这里,然后用 React 构建你令人惊叹的产品:)。否则,请继续阅读。我举了一个例子来解释更多。

假设我们有以下组件。当组件第一次渲染以及每次变化时,我们应该Hello Word登录控制台rand。单击该button更改rand,但我们不会有新的日志,因为没有任何重新渲染state,因为没有更改,所以useEffect没有进行比较,因此它不知道更改。

export default function Comp() {
  let rand = Math.random();
  useEffect(() => {
    console.log("Hello Word");
  }, [rand]);
  return (
      <button onClick={() => { rand = Math.random() }}>
        New value
      </button>
  );
}
Run Code Online (Sandbox Code Playgroud)

让我们对这个相同的组件进行一些更改,如下所示。现在,每次单击该按钮时,组件都会重新渲染,因为我们正在设置 a statesetState并且在重新渲染时,如果 value 的值rand较前一个发生变化,我们将获得一个新的日志。

export default function Comp() {
  const [state, setState] = useState(true); // new line added
  let rand = Math.random();
  useEffect(() => {
    console.log("Hello Word");
  }, [rand]);
  // notice that the click handler has changed
  return (
      <button onClick={() => setState(!state)}>
        New value
      </button>
  );
}
Run Code Online (Sandbox Code Playgroud)