demo url: https://4ikgc.csb.app/
Why the outerHTML always be <h1>abc</h1>
By the way, Why the console seems log everything twice.
Now the content of console.log are:
render h1: {current: null} undefined
render h1: {current: null} undefined
second abc <h1>abc</h1>
forth abc <h1>abc</h1>
first abc <h1>abc</h1>
first abc <h1>abc</h1>
third hello1 <h1>abc</h1>
third hello1 <h1>abc</h1>
fifth hello2 <h1>abc</h1>
fifth hello2 <h1>abc</h1>
render h1: <h1>hello3</h1> <h1>abc</h1>
render h1: <h1>hello3</h1> <h1>abc</h1>
But I thought the right content are:
render h1: {current: null} undefined
second abc <h1>abc</h1>
forth abc <h1>abc</h1>
first abc <h1>abc</h1>
third hello1 <h1>abc</h1>
fifth hello2 <h1>abc</h1>
render h1: <h1>hello3</h1> <h1>hello3</h1>
Hope anyone could help me! much thanks!
import React from "react";
class Hello extends React.Component {
constructor(props) {
super(props);
this.h1 = React.createRef();
this.state = {
name: "abc"
};
}
componentDidMount() {
this.setState((state, props) => {
console.log("first", state.name, this.h1.outerHTML);
return {
name: "hello1"
};
});
console.log("second", this.state.name, this.h1.outerHTML);
this.setState((state, props) => {
console.log("third", state.name, this.h1.outerHTML);
return {
name: "hello2"
};
});
console.log("forth", this.state.name, this.h1.outerHTML);
this.setState((state, props) => {
console.log("fifth", state.name, this.h1.outerHTML);
return {
name: "hello3"
};
});
}
render() {
console.log("render h1:", this.h1, this.h1.outerHTML);
return <h1 ref={ref => (this.h1 = ref)}>{this.state.name}</h1>;
}
}
export default Hello;
Your Hello component have a H1
and where you're using that Hello
component also have another H1
<div className="App">
<Hello />
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
Reason you're getting 2 console.logs
is that how react lifecycle works. Your 1st console.log
in render
happens when the component initially get rendered. After component get rendered react triggers componentDidUpdate
lifecycle method.
Then when you trigger a this.setState
in that method it triggers a re-render of render
again. That's your second console.log
. Also because in your particular case you're setting this.state
multiple times in componentDidUpdate
it triggers multiple state changes.
Also make note that when in development
mode and using react strict <React.StrictMode>
, the setState
get called twice. It is intentional. It won't happen in production.
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
rootElement
);
REF:
https://github.com/facebook/react/issues/12856#issuecomment-390206425
https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects