Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger child re-rendering in React.js

The Parent (MyList in my example) component renders an array thru a Child (MyComponent) component. Parent decides to change properties in the array, what is React way of triggering child re-rendering?

All I came up with is this.setState({}); in Parent after tweaking the data. Is this a hack or a React way of triggering an update?

JS Fiddle: https://jsfiddle.net/69z2wepo/7601/

var items = [   {id: 1, highlighted: false, text: "item1"},   {id: 2, highlighted: true, text: "item2"},   {id: 3, highlighted: false, text: "item3"}, ];  var MyComponent = React.createClass({   render: function() {     return <div className={this.props.highlighted ? 'light-it-up' : ''}>{this.props.text}</div>;   } });  var MyList = React.createClass({   toggleHighlight: function() {     this.props.items.forEach(function(v){       v.highlighted = !v.highlighted;     });      // Children must re-render     // IS THIS CORRECT?     this.setState({});   },    render: function() {     return <div>       <button onClick={this.toggleHighlight}>Toggle highlight</button>       {this.props.items.map(function(item) {           return <MyComponent key={item.id} text={item.text} highlighted={item.highlighted}/>;       })}     </div>;   } });  React.render(<MyList items={items}/>, document.getElementById('container')); 
like image 429
Djam Avatar asked May 04 '15 15:05

Djam


People also ask

How do you force re-render child component React?

Simply use forceUpdate method to force React to Re-Render the component.

How do you trigger re-render React?

Forcing an update on a React class component In any user or system event, you can call the method this. forceUpdate() , which will cause render() to be called on the component, skipping shouldComponentUpdate() , and thus, forcing React to re-evaluate the Virtual DOM and DOM state.

Do child components always re-render?

This doesn't only mean the component's render function will be called, but also that all its subsequent child components will re-render, regardless of whether their props have changed or not.

How do you prevent a child component from re-rendering in React?

memo() If you're using a React class component you can use the shouldComponentUpdate method or a React. PureComponent class extension to prevent a component from re-rendering.


Video Answer


1 Answers

The problem here is that you're storing state in this.props instead of this.state. Since this component is mutating items, items is state and should be stored in this.state. (Here's a good article on props vs. state.) This solves your rendering problem, because when you update items you'll call setState, which will automatically trigger a re-render.

Here's what your component would look like using state instead of props:

var MyList = React.createClass({     getInitialState: function() {         return { items: this.props.initialItems };     },      toggleHighlight: function() {         var newItems = this.state.items.map(function (item) {             item.highlighted = !item.highlighted;             return item;         });          this.setState({ items: newItems });     },      render: function() {         return (             <div>                 <button onClick={this.toggleHighlight}>Toggle highlight</button>                 { this.state.items.map(function(item) {                     return <MyComponent key={item.id} text={item.text}                               highlighted={item.highlighted}/>;                 }) }             </div>         );         } });  React.render( <MyList initialItems={initialItems}/>,               document.getElementById('container') ); 

Note that I renamed the items prop to initialItems, because it makes it clear that MyList will mutate it. This is recommended by the documentation.

You can see the updated fiddle here: https://jsfiddle.net/kxrf5329/

like image 106
Jordan Running Avatar answered Oct 06 '22 08:10

Jordan Running