|
|
@ -122,3 +122,103 @@ var handleToggle = function(enabled) { |
|
|
|
}; |
|
|
|
var myToggleLink = <ToggleLink onToggle={handleToggle} />; |
|
|
|
``` |
|
|
|
|
|
|
|
### Common Patterns |
|
|
|
|
|
|
|
With React your event handlers should be quite small. Large event handlers may |
|
|
|
be symptomatic of code that should be moved into helpers or into `render()`. |
|
|
|
Here are some common usage patterns for event handlers. |
|
|
|
|
|
|
|
#### Updating State |
|
|
|
|
|
|
|
The most common thing to do in response to a user action is to call |
|
|
|
`this.setState()` to update the component's state, which will in turn trigger |
|
|
|
an update to the rendered component. |
|
|
|
|
|
|
|
#### Server Requests |
|
|
|
|
|
|
|
Many event handlers will issue a server request to read or write some data in |
|
|
|
response to an event. The response handler for the request will often call |
|
|
|
`this.setState()`. |
|
|
|
|
|
|
|
#### Invoke a Callback |
|
|
|
|
|
|
|
Your component will often be a small, reusable building block that does not know |
|
|
|
how to respond to a user action. In these situations, we delegate the |
|
|
|
responsibility to the owner by exposing a handler on `this.props`. This is what |
|
|
|
the `ToggleLink` example above is doing. |
|
|
|
|
|
|
|
#### Inter-component Communication |
|
|
|
|
|
|
|
A common scenario involves communicating to **Component A** that a user action |
|
|
|
has occurred on **Component B**. To solve this problem, a common parent to |
|
|
|
both components should listen for the event on **Component B**, update its |
|
|
|
internal state, and pass that data into **Component A**. |
|
|
|
|
|
|
|
For example, say we have two components: **Clicker**, a component that fires an |
|
|
|
`onCountChange` custom event, and **ClickCountLabel**, a component that displays |
|
|
|
the number of clicks that have happened: |
|
|
|
|
|
|
|
```javascript |
|
|
|
var Clicker = React.createClass({ |
|
|
|
getInitialState: function() { |
|
|
|
return {count: 0}; |
|
|
|
}, |
|
|
|
render: function() { |
|
|
|
return <span onClick={this.handleClick}>Click me!</span>; |
|
|
|
}, |
|
|
|
handleClick: React.autoBind(function() { |
|
|
|
this.setState({count: this.state.count + 1}); |
|
|
|
if (this.props.onCountChange) { |
|
|
|
this.props.onCountChange(this.state.count); |
|
|
|
} |
|
|
|
}) |
|
|
|
}); |
|
|
|
|
|
|
|
var ClickCountLabel = React.createClass({ |
|
|
|
render: function() { |
|
|
|
return <p>You have clicked <strong>{this.props.count}</strong> times.</p>; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
var ClickApp = React.createClass({ |
|
|
|
render: function() { |
|
|
|
var count = 0; |
|
|
|
return ( |
|
|
|
<div> |
|
|
|
<Clicker onCountChange={this.handleCountChange} /> |
|
|
|
<ClickCountLabel count={count} /> |
|
|
|
</div> |
|
|
|
); |
|
|
|
}, |
|
|
|
handleCountChange: React.autoBind(function(count) { |
|
|
|
// Somehow update `count`. |
|
|
|
}) |
|
|
|
}); |
|
|
|
``` |
|
|
|
|
|
|
|
In order to communicate the click count from `Clicker` to `ClickCountLabel`, we |
|
|
|
modify `ClickApp` to maintain state that will be passed into `ClickCountLabel`: |
|
|
|
|
|
|
|
```javascript{2-4,6,15} |
|
|
|
var ClickApp = React.createClass({ |
|
|
|
getInitialState: function() { |
|
|
|
return {count: 0}; |
|
|
|
}, |
|
|
|
render: function() { |
|
|
|
var count = this.state.count; |
|
|
|
return ( |
|
|
|
<div> |
|
|
|
<Clicker onCountChange={this.handleCountChange} /> |
|
|
|
<ClickCountLabel count={count} /> |
|
|
|
</div> |
|
|
|
); |
|
|
|
}, |
|
|
|
handleCountChange: React.autoBind(function(count) { |
|
|
|
this.setState({count: count}); |
|
|
|
}) |
|
|
|
}); |
|
|
|
``` |
|
|
|
|
|
|
|
Now when `Clicker` fires the `onCountChange` event, the `ClickCountLabel` will |
|
|
|
get updated! |
|
|
|