Reputation: 31
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);
Upvotes: 2
Views: 197
Reputation: 11760
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>;
};
Upvotes: 2
Reputation: 7890
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])
Upvotes: 2
Reputation: 347
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.
Upvotes: 0
Reputation: 1514
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
}, []);
Upvotes: 2