## 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`,而不必顯示地傳遞它。