Do you want to request a feature or report a bug?
Bug
What is the current behavior?
If the props received undefined value, useEffect understand the value props change, and reload infinity times.
Obviously the data must be handled, but when it gets undefined the infinite reload should not happen.
In the codesandbox example, I force the props checkedItems with undefined, but if I don't pass any props, the default value is undefined, the useEffect understand the value change, and start que infinity loop.
Example below:
https://codesandbox.io/s/aged-river-ypn7y
What is the expected behavior?
Load only one time, because the value undefined not change.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React Typescript
My react version: 16.8.1
My react dom version: 16.8.1
My chrome version: 75.0.3770.142
"@types/react": "16.7.22",
"@types/react-dom": "16.0.11",
Thanks.
Could you please make a codesandbox repro?
Probably comes from your paymentProvider.getPayments();
Follow the code: https://codesandbox.io/s/aged-river-ypn7y
It looks like its coming from your code (it comes from a state changed and state watch via useEffect) , ive also changed the default loading state, please try:
index.tsx
const [isLoading, setIsLoading] = React.useState(true);
const fetchData = async () => {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/todos/1"
);
setIsLoading(false);
};
children.tsx (remove checkedItems from useEffect dependancy)
useEffect(() => {
setChecked(checkedItems);
console.log("checkeditems", checkedItems);
console.log("checked", checked);
}, []);
It looks like its coming from your code (it comes from a state changed and state watch via useEffect) , ive also changed the default loading state, please try:
index.tsxconst [isLoading, setIsLoading] = React.useState(true); const fetchData = async () => { const response = await axios.get( "https://jsonplaceholder.typicode.com/todos/1" ); setIsLoading(false); };
children.tsx(remove checkedItems from useEffect dependancy)useEffect(() => { setChecked(checkedItems); console.log("checkeditems", checkedItems); console.log("checked", checked); }, []);
The example in codesanbox is simple, because this my props don't receive new values and not render again. Remove this props from useEffect param does not help in my actual application.
In my real application I have a global component, and have cases that I pass the props checkedItems and have cases that I don't pass. If I don't pass, the value is undefined, and start the infinity reload.
For the Children component, when prop checkedItems is undefined, it will take default value of an empty array, as you've indicated. It's always a different array whenever Children rerenders, triggering useEffect hook and causing infinite loop.
The solution is to hoist default checkedItems value out of the component so it's always the same empty array. Take a look at https://codesandbox.io/s/romantic-dream-npk8y
Oh, I understand now. Define empty array in the function, it rerender and start the infinity loop. Raising the array out solves the problem. Thank you the explanation!
Most helpful comment
For the Children component, when prop checkedItems is undefined, it will take default value of an empty array, as you've indicated. It's always a different array whenever Children rerenders, triggering useEffect hook and causing infinite loop.
The solution is to hoist default checkedItems value out of the component so it's always the same empty array. Take a look at https://codesandbox.io/s/romantic-dream-npk8y