Redux 的官方 React 绑定。高性能且灵活。
Official React bindings for Redux. Performant and flexible.
React Redux
=========================
Official React bindings for [Redux](https://github.com/gaearon/redux).
Performant and flexible.
[![build status](https://img.shields.io/travis/rackt/react-redux/master.svg?style=flat-square)](https://travis-ci.org/rackt/react-redux) [![npm version](https://img.shields.io/npm/v/react-redux.svg?style=flat-square)](https://www.npmjs.com/package/react-redux)
[![npm downloads](https://img.shields.io/npm/dm/react-redux.svg?style=flat-square)](https://www.npmjs.com/package/react-redux)
[![redux channel on slack](https://img.shields.io/badge/slack-redux@reactiflux-61DAFB.svg?style=flat-square)](http://www.reactiflux.com)
>**Note: There is a project called `redux-react` on NPM that is [completely unrelated](https://github.com/cgarvis/redux-react/issues/1) to the official bindings. This documentation (and any other official Redux documentation) is for `react-redux`.**
## Table of Contents
- [Installation](#installation)
- [React Native](#react-native)
- [Quick Start](#quick-start)
- [API](#api)
- [``](#provider-store)
- [`connect([mapStateToProps], [mapDispatchToProps], [mergeProps])`](#connectmapstatetoprops-mapdispatchtoprops-mergeprops)
- [Troubleshooting](#troubleshooting)
- [License](#license)
## Installation
```
npm install --save react-redux
```
Be careful! **“React” goes first.**
There is a project called `redux-react`, but it is [completely unrelated](https://github.com/cgarvis/redux-react/issues/1).
React Redux requires **React 0.13 or later.**
## React Native
What you get from `react-redux` is for React.
For React Native, import from `react-redux/native` instead.
## Quick Start
React bindings for Redux embrace the idea of [dividing “smart” and “dumb” components](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0).
It is advisable that only top-level components of your app (such as route handlers, for example) are aware of Redux. Components below them should be “dumb” and receive all data via props.
Location
Use React-Redux
To read data, they
To change data, they
“Smart” Components
Top level, route handlers
Yes
Subscribe to Redux state
Dispatch Redux actions
“Dumb” Components
Middle and leaf components
No
Read data from props
Invoke callbacks from props
### “Dumb” components are unaware of Redux
Let’s say we have a `` “dumb” component with a number `value` prop, and an `onIncrement` function prop that it will call when user presses an “Increment” button:
```js
import { Component } from 'react';
export default class Counter extends Component {
render() {
return (
);
}
}
```
### “Smart” components are `connect()`-ed to Redux
Here’s how we hook it up to the Redux Store.
We will use the `connect()` function provided by `react-redux` to turn a “dumb” `Counter` into a smart component. The `connect()` function lets you specify *which exact* state from the Redux store your component wants to track. This lets you subscribe on any level of granularity.
##### `containers/CounterContainer.js`
```js
import { Component } from 'react';
import { connect } from 'react-redux';
import Counter from '../components/Counter';
import { increment } from '../actionsCreators';
// Which part of the Redux global state does our component want to receive as props?
function mapStateToProps(state) {
return {
value: state.counter
};
}
// Which action creators does it want to receive by props?
function mapDispatchToProps(dispatch) {
return {
onIncrement: () => dispatch(increment())
};
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter);
// You can also pass an object instead of defining `mapDispatchToProps`:
// export default connect(mapStateToProps, CounterActionCreators)(Counter);
// Or you can pass `dispatch` down as a prop if you omit `mapDispatchToProps`:
// export default connect(mapStateToProps)(Counter);
// See more recipes in detailed connect() examples below.
```
Whether to put the `connect()` call in the same file as the “dumb” component, or separately, is up to you.
Ask yourself whether you'd want to reuse this component but bind it to different data, or not.
### Nesting
You can have many `connect()`-ed components in your app at any depth, and you can even nest them. It is, however, preferable that you try to only `connect()` top-level components such as route handlers, so the data flow in your application stays predictable.
### Support for Decorators
You might have noticed that we used parens twice when calling `connect()`. This is called partial application, and it lets people
use ES7’s proposed decorator syntax:
```js
// Unstable syntax! It might change or break in production.
@connect(mapStateToProps)
export default class CounterContainer { ... }
```
Don’t forget decorators are experimental! They desugar to function calls anyway as the example above demonstrates.
### Additional Flexibility
This is the most basic usage, but `connect()` supports many other patterns: just passing the vanilla `dispatch()` function down, binding multiple action creators, passing them in an `actions` prop, selecting parts of state and binding action creators depending on `props`, and so on. Check out the `connect()` docs below to learn more.
### Injecting Redux Store
Finally, how do we actually hook it up to the Redux store? We need to create the store somewhere at the root of our component hierarchy. For client apps, the root component is a good place. For server rendering, you can do this in the request handler.
The trick is to wrap the whole view hierarchy into a `{() => ... }` where `Provider` is imported from `react-redux`. One gotcha is that **the child of `Provider` must be a function**. This is to work around an issue about how context (undocumented feature we have to rely on to pass Redux data to components below) works in React 0.13. In React 0.14, you will be able to put your view hierarchy in `` without wrapping it into a function.
```js
import { Component } from 'react';
import { Provider } from 'react-redux';
class App extends Component {
render() {
// ...
}
}
const targetEl = document.getElementById('root');
React.render((
{() => }
), targetEl);
```
## API
### ``
Makes the Redux store available to the `connect()` calls in the component hierarchy below. Normally, you can’t use `connect()` without wrapping the root component in ``. (If you *really* need to, you can manually pass `store` as a prop to every `connect()`ed component, but we only recommend to do this for stubbing `store` in unit tests, or in non-fully-React codebases. Normally, you should just use ``.)
#### Props
* `store`: (*[Redux Store](http://gaearon.github.io/redux/docs/api/Store.html)*): The single Redux store in your application.
* `children`: (*Function*): Unlike most React components, `` accepts a [function as a child](#child-must-be-a-function) with your root component. This is a temporary workaround for a React 0.13 context issue, which will be fixed when React 0.14 comes out.
#### Example
##### Vanilla React
```js
React.render(
{() => }
,
rootEl
);
```
##### React Router 0.13
```js
Router.run(routes,