useEffect缺少依赖项

时间:2019-11-29 00:00:00

标签: reactjs react-hooks eslint

我想在钩子中实现componentDidMount,我想为第一次渲染做某事 ONLY ,所以在useEffect中,我将依赖项数组设置为空,但eslint警告说缺少依赖项。 该怎么解决?

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";

const Child = ({ age }) => {
  useEffect(() => {
    console.log("simulate componentDidMount, age:", age);
  }, []);

  useEffect(() => {
    console.log('simulate componentDidUpdate, age:', age)
  }, [age])

  return <div>age: {age}</div>;
};

const App = () => {
  const [age, setAge] = useState(0);
  const handleOnClick = e => {
    e.preventDefault();
    setAge(a => a + 1);
  };
  return (
    <>
      <Child age={age} />
      <button onClick={handleOnClick}>INCREASE AGE</button>
    </>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

4 个答案:

答案 0 :(得分:3)

它说缺少依赖项,因为您确实在age内使用了useEffect,即使只是为了打印出来,所以eslint可能认为您应该添加{{1} }进行依赖关系列表。

age

答案 1 :(得分:2)

如果您不想禁用eslint,可以执行以下操作:

const [component_mounted, set_component_mounted] = useState(false)

useEffect(() => {
    if(!component_mounted) {
      // Use age here
      set_component_mounted(true)
    }
  }, [age, component_mounted, set_component_mounted])

答案 2 :(得分:2)

您可以将第一个渲染存储在ref中,并在isFirstRender.current为true时执行您需要做的事情,这样,您无需在效果上添加age即可添加任何内容,并且可以合并cDM和cDU在一起,将生命周期存储在状态中对我来说没有意义。

const Child = ({ age }) => {
  const isFirstRender = useRef(true);

  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false;
      console.log("simulate componentDidMount, age:", age);
      return
    }
    console.log('simulate componentDidUpdate, age:', age);
  }, [age]);

  return <div>age: {age}</div>;
};

如果您想重复使用它,还可以将其提取到自定义钩子中

const useIsFirstRender = () => {
  const isFirstRender = useRef(true);

  useEffect(() => {
    isFirstRender.current = false;
  }, []);

  return isFirstRender.current;
};

const Child = ({ age }) => {
  const isFirstRender = useIsFirstRender();

  useEffect(() => {
    if (isFirstRender) {
      console.log("simulate componentDidMount, age:", age);
      return;
    }
    console.log('simulate componentDidUpdate, age:', age)
  }, [age, isFirstRender]);

  return <div>age: {age}</div>;
};

答案 3 :(得分:0)

反应并不关心您如何使用状态。因此,打印年龄与将年龄放入某些逻辑计算没有区别。埃斯林特做得对。