Skip to content

Commit 3b0f705

Browse files
committed
Merge pull request #623 from chenglou/tips-communication
docs tips parent-child communication 2
2 parents 50d190f + 23eac0b commit 3b0f705

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

docs/_data/nav_tips.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@
2828
title: False in JSX
2929
- id: communicate-between-components
3030
title: Communicate Between Components
31+
- id: expose-component-functions
32+
title: Expose Component Functions

docs/tips/14-communicate-between-components.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ title: Communicate Between Components
44
layout: tips
55
permalink: communicate-between-components.html
66
prev: false-in-jsx.html
7+
next: expose-component-functions.html
78
---
89

910
For parent-child communication, simply [pass props](/react/docs/multiple-components.html).
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
id: expose-component-functions
3+
title: Expose Component Functions
4+
layout: tips
5+
permalink: expose-component-functions.html
6+
prev: communicate-between-components.html
7+
---
8+
9+
There's another (uncommon) way of [communicating between components](/react/tips/communicate-between-components.html): simply expose a method on the child component for the parent to call.
10+
11+
Say a list of todos, which upon clicking get removed. If there's only one unfinished todo left, animate it:
12+
13+
```js
14+
/** @jsx React.DOM */
15+
16+
var Todo = React.createClass({
17+
render: function() {
18+
return <div onClick={this.props.onClick}>{this.props.title}</div>;
19+
},
20+
21+
//this component will be accessed by the parent through the `ref` attribute
22+
animate: function() {
23+
console.log('Pretend %s is animating', this.props.title);
24+
}
25+
});
26+
27+
var Todos = React.createClass({
28+
getInitialState: function() {
29+
return {items: ['Apple', 'Banana', 'Cranberry']};
30+
},
31+
32+
handleClick: function(i) {
33+
var items = this.state.items;
34+
items.splice(i, 1);
35+
this.setState({items: items}, function() {
36+
if (items.length === 1) {
37+
this.refs.item0.animate();
38+
}
39+
}.bind(this));
40+
},
41+
42+
render: function() {
43+
return (
44+
<div>
45+
{this.state.items.map(function(item, i) {
46+
var boundClick = this.handleClick.bind(this, i);
47+
return (
48+
<Todo onClick={boundClick} key={i} title={item} ref={'item' + i} />
49+
);
50+
}, this)}
51+
</div>
52+
);
53+
}
54+
});
55+
56+
React.renderComponent(<Todos />, mountNode);
57+
```
58+
59+
Alternatively, you could have achieve 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.

0 commit comments

Comments
 (0)