Reputation: 3489
I'm experimenting with ReactJS and I'm trying to understand how child component rendering is triggered. In ReactJS, if I set up an example like this:
var externalCounterVar = 10
class Counter extends React.Component {
constructor(props){
super(props);
this.state = props;
}
render() {
console.log('rendering counter')
return (
<div> {externalCounterVar} </div>
)
}
}
class Main extends React.Component {
constructor(props){
super(props);
}
handleClick() {
externalCounterVar += 1;
}
rerender(){
this.render();
}
render() {
console.log('rendering');
return (
<div>
<button onClick={this.rerender.bind(this)} />
<Counter counter={externalCounterVar} />
</div>
)
}
}
ReactDOM.render(<Main />, document.getElementById('root'));
I'm not sure I understand why when you "rerender" it calls the render method of Main but not Counter? It seems like it should call both render methods since it's rendering Main and Counter is a child of Main.
So when rerender is called, 'rendering' will print but 'rendering counter' will not.
Upvotes: 0
Views: 93
Reputation: 17091
In this case you don't have to use rerender
method, also with purpose re-render all child components you need update state with method setState
. And also accordingly to this you have to "move state up".
Here my example:
class Counter extends React.Component {
render() {
console.log('rendering counter');
return (<div> {this.props.counter} </div>);
}
}
class Main extends React.Component {
constructor(props){
super(props);
this.state = {counter: props.counter};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({counter: ++prevState.counter}));
}
render() {
console.log('rendering');
return (
<div>
<button onClick={this.handleClick} />
<Counter counter={this.state.counter} />
</div>
);
}
}
var externalCounterVar = 10;
ReactDOM.render(
<Main counter={externalCounterVar} />,
document.getElementById('root')
);
Upvotes: 1
Reputation: 7774
In some situations you can use this.forceUpdate()
to call re-render.
But, if you can not do this, do not do.
https://facebook.github.io/react/docs/react-component.html#forceupdate
Upvotes: 0
Reputation: 735
It looks like you're overlooking one of the main benefits of using React, namely how state works.
this.render
within a React componentthis.state = ...
this.setState
to set your state.Rewritten, your code should look something like the following:
const externalCounterVar = 10
class Counter extends React.Component {
render() {
console.log('rendering counter')
return (
<div> {this.props.counter} </div>
)
}
}
class Main extends React.Component {
state = {
counter: externalCounterVar
}
handleClick() {
this.setState({counter: this.state.counter + 1});
}
render() {
console.log('rendering');
return (
<div>
<button onClick={this.handleClick.bind(this)} />
<Counter counter={this.state.counter} />
</div>
)
}
}
By calling this.setState
, React automatically knows it needs to rerender your component, and as a result, all child components will also be rerendered.
Hope this helps!
Upvotes: 3