From f228f65f018482e6630e27045a09eb14014c199c Mon Sep 17 00:00:00 2001 From: Cheng Lou Date: Sun, 1 Dec 2013 22:13:58 -0500 Subject: [PATCH] docs tips expose component function --- _data/nav_tips.yml | 2 + tips/14-communicate-between-components.md | 1 + tips/15-communicate-between-components-2.md | 59 +++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 tips/15-communicate-between-components-2.md diff --git a/_data/nav_tips.yml b/_data/nav_tips.yml index 95824f28..63875913 100644 --- a/_data/nav_tips.yml +++ b/_data/nav_tips.yml @@ -28,3 +28,5 @@ title: False in JSX - id: communicate-between-components title: Communicate Between Components + - id: expose-component-functions + title: Expose Component Functions diff --git a/tips/14-communicate-between-components.md b/tips/14-communicate-between-components.md index 84c1a9fe..e302e007 100644 --- a/tips/14-communicate-between-components.md +++ b/tips/14-communicate-between-components.md @@ -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). diff --git a/tips/15-communicate-between-components-2.md b/tips/15-communicate-between-components-2.md new file mode 100644 index 00000000..476d9ee1 --- /dev/null +++ b/tips/15-communicate-between-components-2.md @@ -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
{this.props.title}
; + }, + + //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); + this.setState({items: items}, function() { + if (items.length === 1) { + this.refs.item0.animate(); + } + }.bind(this)); + }, + + render: function() { + return ( +
+ {this.state.items.map(function(item, i) { + var boundClick = this.handleClick.bind(this, i); + return ( + + ); + }, this)} +
+ ); + } +}); + +React.renderComponent(, 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.