Reputation: 590
I've taken my app to bare minimum to try to understand why it is infinite looping...but I don't get it.
const App = () => {
console.log("just logging that the app ran!")
const [data, setData] = useState('initial state');
const getAsset = async () => {
console.log("logging that getAsset ran!")
setData("new state!")
console.log(data)
}
getAsset();
return (
<div >
{data}
</div>
);
}
export default App;
Any pointers?
The error message:
react-dom.development.js:14997 Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
Upvotes: 0
Views: 3631
Reputation: 124
you can use some thing like this
fetchSummary(Props).then((d)=>{
setSummary(d);
setStatus('success');
setModel(d.model);
console.log("response after call" + JSON.stringify(d));
})
useEffect(() => {
fetchData();
},[]);
//-> triggers one time if we specify empty array
-> fetchSummary is promise function
-> on promise function you can call then
-> then block will call only once promise is resolved
Upvotes: 0
Reputation: 26
Your component will re-render on each action performed, re-running the async function again and again. A way to avoid this is using the useEffect hook with a dependency of your choice. This way, the async function will only run when it fulfils a certain condition.
Upvotes: 0
Reputation: 9662
Just call the getAsset
inside useEffect
hook. Not sure why the function is made async
though. In your case setData
causes a re-render and again calls the getAsset
function which results in a loop
Working sandbox : https://codesandbox.io/s/react-hooks-example-forked-0rqb9?file=/src/App.js
const App = () => {
const [data, setData] = useState("initial state");
useEffect(() => {
getAsset();
}, []);
const getAsset = async () => {
setData("new state!");
};
return <div>{data}</div>;
};
export default App;
Upvotes: 2
Reputation: 159
The problem is that App is getting re-run by React every time the state changes, meaning getAsset being called directly in App without any checks to see if it has run already, will cause a loop.
// Runs when the component is rendered.
const App = () => {
// ...
getAsset(); // Sets state, re-rendering app.
// ...
return (
<div >
{data}
</div>
);
}
To fix, check to make sure state is only set once or when the new state would be different so no looping behavior can occur.
Upvotes: 1
Reputation: 509
your code call getAsset() every time component render and getAsset setState (setData) and when you change state the component rerender and it call getAsset again and rerender again ............
you need to call it on mount so use useEffect
const App = () => {
console.log("just logging that the app ran!")
const [data, setData] = useState('initial state');
const getAsset = async () => {
console.log("logging that getAsset ran!")
setData("new state!")
console.log(data)
}
useEffect(() => {
getAsset();
},[])
return (
<div >
{data}
</div>
);
}
export default App;
Upvotes: 1