Reputation: 3583
I'm confused why function components (non class components don't confuse with functional) are constructed twice when state changes?
My understanding was that the function is constructed once just like a class' component constructor?
Note: React is NOT running in strict mode.
Sample code:
index.js:
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, // notice no strict mode
rootElement
);
Eg 1: LogStatement called once - simple and obvious:
function App1() {
console.log("App constructed");
return <div>Hello</div>;
}
Eg 2: LogStatement called twice - not quite obvious but maybe its due to setDidMount ? :
function App2() {
console.log("App constructed");
const [didMount, setDidMount] = useState(false);
useEffect(() => {
setDidMount(true);
}, []);
return <div>Hello</div>;
}
Eg 3: LogStatement called twice. no matter how many independent state variables:
function App3() {
console.log("App constructed:" + i++);
const [didMount, setDidMount] = useState(false);
const [someState, setSomeState] = useState("empty");
useEffect(() => {
setDidMount(true);
}, []);
useEffect(() => {
setSomeState("full");
}, []);
return <div>Hello</div>;
}
Finally class component
Eg 4: LogStatement called once - as expected
class App4 extends Component {
constructor() {
super();
this.state = {
didMount: false
};
console.log("App constructed:" + i++);
}
componentDidMount() {
this.setState({
didMount: true
});
}
render() {
return <div>Hello</div>;
}
}
Upvotes: 0
Views: 1167
Reputation: 84982
My understanding was that the function is constructed once just like a class' component constructor?
It's not constructed at all, that's just a class thing. Putting a log statement in the body of a function component is roughly equivalent to putting it in the render
method of a class component. So your log is telling you how many times the component rendered. Setting state causes rendering (usually), so by calling setDidMount(true)
, you are rerendering the component.
Upvotes: 1