## react-redux
先添加一个`Counter`页面。
~~~
cd src/pages
mkdir Counter
touch Counter/Counter.js
~~~
`src/pages/Counter/Counter.js`
~~~
import React, { Component } from 'react'
export default class Counter extends Component {
render() {
return (
<div>
<div>当前计数为(显示redux计数)</div>
<button onClick={() => { console.log('调用自增函数') }}>自增</button>
<button onClick={() => { console.log('调用自减函数') }}>自减</button>
<button onClick={() => { console.log('调用重置函数') }}>重置</button>
</div>
)
}
}
~~~
修改路由,增加`Counter`。
`src/router/router.js`
~~~
import React from 'react'
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'
import Home from 'pages/Home/Home'
import Page from 'pages/Page/Page'
import Counter from 'pages/Counter/Counter'
export default () => (
<Router>
<div>
<ul>
<li><Link to="/">首页</Link></li>
<li><Link to="/page">Page</Link></li>
<li><Link to="/counter">Counter</Link></li>
</ul>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/page" component={Page} />
<Route path="/counter" component={Counter}/>
</Switch>
</div>
</Router>
// 相当于return 一个(组件)
)
~~~
现在点击按钮呢,调用的是`console.log`函数,下一步我们让`Counter`组件和`Redux`联合起来,使`Counter`能获得到`Redux`的`state`,并且能发射`action`。
我们可以使用上一节用到的`testRedux`的方法使用`store.subscribe`手动监听~手动引入`store`,但这样是很繁琐的,所以`react-redux`提供了一个方法`connect`,下面是这个方法的介绍:
> 容器组件就是使用 store.subscribe() 从 Redux state 树中读取部分数据,并通过 props 来把这些数据提供给要渲染的组件。你可以手工来开发容器组件,但建议使用 React Redux 库的 connect() 方法来生成,这个方法做了性能优化来避免很多不必要的重复渲染。
>
`connect`接受两个参数,一个`mapStateToProps`,就是把`redux`的`state`转为**组件**的`Props`,还有一个参数是`mapDispatchToProps`,就是把发射`action`的方法转为`Props`的属性函数。
先来安装`react-redux`。
`npm install --save react-redux`
然后修改原来的`Counter`组件:
`src/pages/Counter/Counter.js`
~~~
import React, { Component } from 'react'
import { increment, decrement, reset } from 'actions/counter'
import { connect } from 'react-redux'
// 先写connect的两个参数函数:
const mapStateToProps = (state) => {
return {
counter: state.counter
}
}
const mapDispatchToProps = (dispatch) => {
return {
increment() {
dispatch(increment())
},
decrement() {
dispatch(decrement())
},
reset() {
dispatch(reset())
}
}
}
// 不要默认导出Counter,删掉export default
class Counter extends Component {
// 通过connect 这里可以直接拿到this.props
render() {
return (
<div>
<div>当前计数为{this.props.counter.count}</div>
<button onClick={() => this.props.increment() }>自增</button>
<button onClick={() => this.props.decrement() }>自减</button>
<button onClick={() => this.props.reset() }>重置</button>
</div>
)
}
}
// 最后导出用connect 处理后的Counter。
export default connect(mapStateToProps, mapDispatchToProps)(Counter)
~~~
下一节我们要把`store`,要让所有的容器组件都可以访问到`Redux store`,一种方式是把它以`props`的形式传入到所有容器组建中。但这样太麻烦了,因为必须要用`store`把展示组件包裹一层,仅仅是因为恰好在组件树中渲染一个容器组件。
> 建议的方式是:使用指定的`React Redux`组件 来 魔法般的 让所有的容器组件都可以访问`store`,而不必显示地传递它。