I am passing the increment function to a list of children (Row), but the count is never actually changed, I know that something about doing this in the children's useEffect is off. But I am still not able to understand this behavior.
Also, I am not setting the dependency array, because in this case, the count will run infinitely.
import { useCallback, useEffect, useState } from "react";
import "./styles.css";
const list = ["One", "Two", "Three"];
export default function App() {
const [count, setCount] = useState(0);
const handleOnClick = useCallback(() => {
setCount(count 1);
}, [count]);
useEffect(() => {
if (list.length === count) {
alert("yaaay!");
}
}, [count]);
return (
<div className="App">
<h1>Count is: {count}</h1>
{list.map((item) => (
<Row key={item} name={item} addOne={handleOnClick} />
))}
</div>
);
}
const Row = ({ addOne, name }) => {
useEffect(() => {
addOne();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return <p>{name}</p>;
};
The output is:
Count is: 1
One
Two
Three
Expected:
Count is: 3
One
Two
Three
CodePudding user response:
okay i've created a demo
Couple of things. first, you need to set the useState values through the callback function since we are updating the counter value continuously
Secondly, need to use useRef
in the child component to make sure child component is visited In each iteration. Do the checking inside child component useEffect
export default function App() {
const [count, setCount] = React.useState(0);
const handleOnClick = React.useCallback(() => {
setCount((count) => count 1);
}, [count, setCount]);
React.useEffect(() => {
if (list.length === count) {
alert('yaaay!');
}
}, [count]);
return (
<div className="App">
<h1>Count is: {count}</h1>
{list.map((item) => (
<Row key={item} name={item} addOne={handleOnClick} />
))}
</div>
);
}
const Row =({ addOne, name }) => {
const dataFetchedRef = React.useRef(false);
React.useEffect(() => {
if (dataFetchedRef.current) return;
dataFetchedRef.current = true;
addOne();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [name]);
return <p>{name}</p>;
};