Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs tips parent-child communication 2 #623

Merged
merged 1 commit into from
Dec 30, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/_data/nav_tips.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@
title: False in JSX
- id: communicate-between-components
title: Communicate Between Components
- id: expose-component-functions
title: Expose Component Functions
1 change: 1 addition & 0 deletions docs/tips/14-communicate-between-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ title: Communicate Between Components
layout: tips
permalink: communicate-between-components.html
prev: false-in-jsx.html
next: expose-component-functions.html
---

For parent-child communication, simply [pass props](/react/docs/multiple-components.html).
Expand Down
59 changes: 59 additions & 0 deletions docs/tips/15-communicate-between-components-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
id: expose-component-functions
title: Expose Component Functions
layout: tips
permalink: expose-component-functions.html
prev: communicate-between-components.html
---

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.

Say a list of todos, which upon clicking get removed. If there's only one unfinished todo left, animate it:

```js
/** @jsx React.DOM */

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(i) {
var items = this.state.items;
items.splice(i, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you noticed it, but you mutate this.state here. Perhaps one could prefer filtering instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, though my preference is to keep the entry simple and not make newcomers wonder about too many things at the time. But I guess this isn't too much of an overhead.

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

React.renderComponent(<Todos />, mountNode);
```

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small typo: 'could have achieved' or just "could achieve" (depending on the rest or the sentence)