2

I want to implement componentDidMount in hooks that I want to do something for the first rendering ONLY, so in the useEffect, I set the dependency array as empty, but eslint has the warning that dependency is missing. how to solve it?

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 Answers 4

2

You can store the first render in a ref and do what you need to do when isFirstRender.current is true, this way you don't need to add anything but age to your effect and can combine cDM and cDU together, storing the lifecycle in state doesn't make sense to me.

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>;
};

You can also extract it into a custom hook if you want to reuse it

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>;
};
Sign up to request clarification or add additional context in comments.

Comments

2

It says the dependency is missing because you do use age inside your useEffect, even if it's just for printing it out, so eslint probably believes you should add age do the dependency list.

useEffect(() => {
    console.log("simulate componentDidMount, age:", age); //age is being used here
  }, []);

4 Comments

if I add age into dependency, later when age is updated, the function inside useEffect would be invoked again. I want to implement something similar to componentDidMount which is invoked only once
I understand, but if you want to print out age in that useEffect while still keeping the componentDidMount, you'll have to ignore the warning.
do you reckon if it is better to have a local state to record if it is first rendering?
@HuanLi - better to have local state to record first rendering, no in my opinion too complicated. You know the purpose of your code better than eslint, just suppress the warning. I use }, []); // eslint-disable-line all the time.
2

You could do something like this if you don't want to disable 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])

1 Comment

One point for correct code, but how noisy is that? (compared to a linting comment)
0

React doesn't care how you use the state. So printing the age has no difference from putting the age in some logic computing. Eslint did right.

1 Comment

You don't get my point. I would like to implement componentDidMount without eslint warning

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.