@spicyj
I'm implementing a wizard framework, and the basic design is like below
here is the sample code of a wizard page
export default class BusinessInfoPage extends WizardPageBase {
submit() {
let newState = Object.assign({},{
submit:true
})
this.setState(newState)
}
render() {
alert('current wizard page is re-rendered...')
let [title, subTitle, breadCrumb] = ['Tell us about your business',
'First we need some information about your company']
return (<WizardPage title={title} subTitle={subTitle}>
<BusinessInfoForm onSubmit={this.onSubmit}
prestine={this.state.submit}/>
</WizardPage>)
}
}
the problem is that, see I'm using Object.assign to set new state in the current wizard page, and I can see that every time I click the 'Next' button on the wizard container, the alert box pops up saying 'current wizard page is re-rendered'. However, the child component of the wizard page is not (I have an alert box on BusinessInfoForm's render function as well).
I can understand that for the child component, which is BusinessInfoForm , since the passed in prop remains the same (prestine: [boolean] true), there is no need for it to re-render. So the behaviour kind of makes sense.
However, when a parent Component gets re-rendered, shouldn't all its children component all get destroyed all re-constructed again?
but it seems like all the children components are cached, and are only re-rendered when needed...
I know that I may call forceUpdate to force children components re-render, or simply pass in a new object instead of Boolean. I'm more interested in how react framework is designed than finding a solution for that.
(yeah,, I know I can debug the source code,, but I don't want to go that far)
Cheers
render() can be called by React many times, and it isn鈥檛 destructive. React will compare what you return from render(), and use that to choose what to mount and what to unmount.
If you move the alert to componentDidMount, you will see what really gets mounted.
thanks for your comments.
I think I've got the answer

In the example above, since shouldComponentUpdate returned false for the subtree rooted at C2, React had no need to generate the new virtual DOM, and therefore, it neither needed to reconcile the DOM. Note that React didn't even have to invoke shouldComponentUpdate on C4 and C5.
since shouldComponentUpdate returned false for the subtree rooted at C2, React had no need to generate the new virtual DOM, i.e C2's render won't get invoked
That鈥檚 right. But even if render() is invoked, it鈥檚 generally okay. Unless you have performance problems when testing with production build of React, don鈥檛 worry about adding shouldComponentUpdate.
I鈥檒l close since it doesn鈥檛 appear to be an issue.
just for other people's reference
class C1 extends Component{
constructor(){
this.state = {
para2C3 : false
}
}
onClick (){
this.setState({para2C3 :true})
}
render(){
return(
<div>
<C2 />
<C3 para={this.state.para2C3} />
<button onClick={this.onClick.bind(this)}>This is what the diagram is all about</button>
</div>
)
}}
also, I think what it means for C8 is that, it render a transformed version of the changed props. e.g. C1's state changed from 1 to 3, and pass the value to C3, causing C3 to re-render. C3 then forward the prop to both C6 and C8, causing them to re-render as well. C6 blindly render the para, while C8 's render logic could be
{ (this.props.para2C3 % 2 ) === 0? 'even': 'odd'
Therefore, both SCU and vDOMEq return true (i.e. vDOM compare returns true, no DOM reconciliation is required)
I personally find these kind of discussion helpful, as it help me to understand how react works. thanks Dan!
import React,{Component} from 'react';
class Parent extends Component {
constructor(props){
super(props)
this.state={
internal:'',
msg:'default'
}
}
internalChange(){
this.setState({internal:'new'})
}
render(){
bin.log('parent re-render')
return (
<div>
<Child msg={this.state.msg} />
<button onClick={this.internalChange.bind(this)}>internal change</button>
</div>
)}
}
class Child extends Component{
//shouldComponentUpdate(nextProps, nextState){
//console.log('insert your break point here')
// you will find that this.props != nextProps,
// becuase when parent gets re-rendered triggered by setState, it builds it
// new VDOM, which is ReactElement(s);
// the nextProps is the prop passed to the new ReactElement, and obviously
// nextProps and this.props points to different object and thus they are not shalldow equal
// to each other.
// child gets re-rendered
//}
render(){
bin.log('child re-render')
const {msg} = this.props
return <h1>msg:{msg}</h1>
}
}
export default Parent;
this looks relevant : https://stackoverflow.com/questions/44642191/react-childrens-render-method-starts-after-parents-render-method-has-fin
can someone please comment on ?
How is it possible that if A has child B then A's render runs first and only after that runs B's render ?
How is this implemented ?
Most helpful comment
I鈥檒l close since it doesn鈥檛 appear to be an issue.