【问题标题】:useEffect is not called when dependencies change依赖项更改时不调用 useEffect
【发布时间】:2022-04-28 10:22:58
【问题描述】:
import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const [minus, setMinus] = useState(3);
  const ref = useRef(null);

  const handleClick = () => {
    setMinus(minus - 1);
  };

  console.log(
    "--> ref and state",
    ref.current?.innerHTML ?? ref.current,
    minus
  );

  // first useEffect
  useEffect(() => {
    console.log(`denp[ref.current] >`, ref.current?.innerHTML ?? ref.current);
  }, [ref.current]);

  // second useEffect
  useEffect(() => {
    console.log(`denp[minus]>`, ref.current?.innerHTML ?? ref.current);
  }, [minus]);

  return (
    <div className="App">
      {(minus >= 0 || minus <= -5) && <h1 ref={ref}>num: {minus}</h1>}
      <button onClick={handleClick}>minus</button>
    </div>
  );
}

export default App;

在第一次渲染时:运行第一个 useEffect 并注销:denp[ref.current] > num: 3

我按下按钮,状态减号更新为2,组件重新渲染

在第二次渲染时:运行第一个 useEffect 并注销:denp[ref.current] > num: 2

我按下按钮,状态减号更新为1,组件重新渲染

在第三次渲染时:第一个 useEffect 不再运行

为什么第一个 useEffect 没有在第三个渲染上运行?

此处的实时代码:https://codesandbox.io/s/brave-mayer-3f8zsl

【问题讨论】:

  • ref.current 似乎不是一个可靠的依赖项,因为 React 发出了这个警告:React Hook useEffect 有一个不必要的依赖项:'ref.current'。排除它或删除依赖数组。像 'ref.current' 这样的可变值不是有效的依赖项,因为改变它们不会重新渲染组件。 (react-hooks/exhaustive-deps)
  • 是的,我阅读了警告和文档,但我不知道到底发生了什么?你能解释一下每次重新渲染的作用吗?
  • 很遗憾,我不知道这里发生了什么,抱歉

标签: reactjs use-effect use-ref


【解决方案1】:

如果你真的想使用 ref 作为依赖,那么使用 ref.current.innerHTML 而不是 ref.current。 我用 ref.current.innerHTML 对其进行了测试,它对我有用 希望能帮到你

【讨论】:

  • 是的,它起作用了,也许它与作为 DOM 节点的 ref.current 有关。第二次和第三次渲染的DOM Node值相同但不同
【解决方案2】:

我猜你不应该依赖 ref 作为依赖,因为它不会触发更新,正如 here 所说的那样。

【讨论】:

  • 是的,但我真的很想知道到底发生了什么?我这样做了,但在第三次渲染中,我希望调用 useEffect - 第一次渲染 - state: 3 - ref: null - render DOM → update ref = 3 - run useEffect → log ref 3 - second render - state: 2 - ref : 3 - 比较旧 ref (null) 与新 ref (3) - 渲染 DOM → 更新 ref = 2 - 运行 useEffect → 记录 ref 2 - 第三次渲染 - 状态 - ref 0 - 比较旧 ref (3) 与新 ref (0 ) - 渲染 DOM → 更新 ref = null - 运行 useEffect → 记录 ref null
  • 是的,我同意这很奇怪
【解决方案3】:

如果您使用的是 Next.JS(可能适用于任何 SSR),我建议您还将依赖项设置为 ref.current?.innerHTML,然后它就会起作用。

【讨论】:

    猜你喜欢
    • 2020-05-19
    • 2020-01-04
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 2020-12-19
    • 2020-03-24
    相关资源
    最近更新 更多