There's another (uncommon) way of communicating between components: simply expose a method on the child component for the parent to call.
Say a list of todos, which upon clicking get removed. If there's only one unfinished todo left, animate it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | var Todo = React.createClass({ render: function () { return <div onClick={ this .props.onClick}>{ this .props.title}</div>; }, //this component will be accessed by the parent through the `ref` attribute animate: function () { console.log( 'Pretend %s is animating' , this .props.title); } }); var Todos = React.createClass({ getInitialState: function () { return {items: [ 'Apple' , 'Banana' , 'Cranberry' ]}; }, handleClick: function (index) { var items = this .state.items.filter( function (item, i) { return index !== i; }); this .setState({items: items}, function () { if (items.length === 1) { this .refs.item0.animate(); } }.bind( this )); }, render: function () { return ( <div> { this .state.items.map( function (item, i) { var boundClick = this .handleClick.bind( this , i); return ( <Todo onClick={boundClick} key={i} title={item} ref={ 'item' + i} /> ); }, this )} </div> ); } }); ReactDOM.render(<Todos />, mountNode); |
Alternatively, you could have achieved this by passing the todo
an isLastUnfinishedItem
prop, let it check this prop in componentDidUpdate
, then animate itself; however, this quickly gets messy if you pass around different props to control animations.
Please login to continue.