Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
14
rated 0 times [  21] [ 7]  / answers: 1 / hits: 131522  / 9 Years ago, mon, may 4, 2015, 12:00:00

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'));

More From » reactjs

 Answers
7

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/


[#66755] Saturday, May 2, 2015, 9 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
devinjadong

Total Points: 711
Total Questions: 117
Total Answers: 100

Location: Andorra
Member since Sat, May 27, 2023
1 Year ago
devinjadong questions
Thu, Feb 17, 22, 00:00, 2 Years ago
Wed, Dec 8, 21, 00:00, 2 Years ago
Tue, Oct 27, 20, 00:00, 4 Years ago
Fri, Oct 18, 19, 00:00, 5 Years ago
;