Reputation: 987
import React from 'react';
import Test from './Test';
function App() {
return (
<Test />
);
}
export default App;
import React, { useState } from "react";
const Test = () => {
const [stuff, setStuff] = useState({ a: "alpha", b: "alpha" });
setStuff({ // this causes infinite loop!
...stuff, // removing setStuff() fixes it.
a: "omega"
});
return <p>{JSON.stringify(stuff)}</p>;
};
export default Test;
I'm using useState() inside Test.js and setStuff() causes infinite loop.
Can someone explain why? And how to fix it (if I want to call setStuff to update stuff)?
Here's working codesandbox: https://codesandbox.io/s/loving-jennings-pr3nl
Upvotes: 1
Views: 271
Reputation: 2188
The simple rule is "don't setState in render function", because setState will trigger a render function, and if in render function, you setState, then it goes on and on and on.
You should bind "setState" to an event, like a mouse click, a keyboard press, or component finish loading event, and setState in that event.... but never never in render function.
In Class Component
import React from 'react'
class Test extends React.Component {
render() {
// Don't setState here.
return (<div>test</div>)
}
}
In functional Component
const Test = () => {
// Don't setState here.
return (<div>test</div>)
}
** Update
Example of how to use setState
In Class Component
import React from 'react'
class Test extends React.Component {
state = {
value: 4
}
handleClickAdd = (e) => {
const currentValue = this.state.value;
this.setState({ value: currentValue + 1 }); // set currentValue + 1 as a new state value.
}
render() {
// Don't setState here.
return (
<div>
test {this.state.value}
<button onClick={this.handleClickAdd}>Add</button>
</div>
)
}
}
In functional Component
const Test = () => {
const [value, setValue] = useState(4);
const handleClickAdd = e => {
setValue(value + 1);
}
// Don't setState here.
return (
<div>
test {value}
<button onClick={handleClickAdd}>Add</button>
</div>
)
}
Upvotes: 1
Reputation: 987
This works
const doStuff=()=>{
setStuff({
...stuff,
a: "omega"
});
};
useEffect(doStuff,[]);
Expected output:
{"a":"omega","b":"alpha"}
Upvotes: 0