接著上一篇,來看看上一篇目錄結(jié)構(gòu)

再來看看index.js,可以看到,只是引用了HelloWorld,雖然引用了reducers,但是并沒有用到,所以上一篇僅僅是寫了一個(gè)react的hello world,還沒有redux的概念在里面
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import reducers from './reducer'
import HelloWorld from './components/helloWorld'
const store = createStore(reducers,{text:'hello world'})
const rootEl = document.getElementById('root')
const render = () => ReactDOM.render(
<HelloWorld></HelloWorld>,
rootEl
)
render()
本文將一步步介紹如何去添加redux,首先看看目錄結(jié)構(gòu)

1.actions,理解成actions創(chuàng)建函數(shù)
import { CHANGE_TEXT } from '../actionsType'
export function changeText(text) {
return {
type: CHANGE_TEXT,
payload: text
}
}
定義了一個(gè)action,觸發(fā)CHANGE_TEXT,并把形參text賦值給payload,比較簡(jiǎn)單
2.actionsType,以常量定義action
export const CHANGE_TEXT = 'CHANGE_TEXT'
這個(gè)更簡(jiǎn)單,定義了一個(gè)action。當(dāng)應(yīng)用規(guī)模越來越大時(shí),建議使用單獨(dú)的模塊或文件來存放 action
3.components,展示組件庫,里面包含了一個(gè)helloWorld組件
import React, { Component, PropTypes } from 'react';
// @pureRender
export default class HelloWorld extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentWillReceiveProps(newProps){
console.log(newProps)
}
render() {
return (
<div>
<button onClick={()=>{this.props.onClick(Math.random())}}>change Text</button>
<div>{this.props.text}</div>
</div>
)
}
}
這是一個(gè)helloWorld組件,比較簡(jiǎn)單,從props中獲取了一個(gè)onClick和text
4.containers ,容器組件庫
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux';
import * as HelloWorldActions from '../actions/HelloWorld'
import HelloWorld from '../components/helloWorld'
// @pureRender
class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
}
render() {
const { helloChan, helloWorldActons } = this.props
return (
<div>
<HelloWorld onClick={helloWorldActons.changeText} text= {helloChan.text}></HelloWorld>
</div>
)
}
}
const mapStateToProps = state => state
const mapDispatchToProps = dispatch => ({
helloWorldActons: bindActionCreators(HelloWorldActions, dispatch)
});
export default connect(mapStateToProps, mapDispatchToProps)(App);
可以看見這個(gè)組件稍微有點(diǎn)復(fù)雜,其中用到了react-redux中的connect,redux中的bindActionCreators,來看看定義
connect
算了,還是不看定義了,比較難懂,可以理解成它是react和redux的連接器,而且它確實(shí)是。它接受兩個(gè)參數(shù)mapStateToProps,mapDispatchToProps,前者指定如何把當(dāng)前 Redux store state 映射到展示組件的 props 中,后者接收 dispatch()
方法并返回期望注入到展示組件的 props 中的回調(diào)方法。
看不懂是吧,實(shí)例講解下
首先,mapStateToProps中的參數(shù)state就是在定義reducer時(shí)的state,這個(gè)一會(huì)兒再講,首先看看state的結(jié)構(gòu)
{ text: 'hello world',name:'default name',config:{name:'張三',sex:'男'} }
如果如下定義mapStateToProps
const mapStateToProps = state => state
那么在打印當(dāng)前props時(shí),得到的結(jié)果如下

如果如下定義mapStateToProps
const mapStateToProps = state => {return {config:state.helloChan.config}}
再來看看結(jié)果是什么

看出區(qū)別了嗎?其實(shí)還是回歸到定義了,如何把當(dāng)前 Redux store state 映射到展示組件的 props 中。
bindActionCreators
再來看mapDispatchToProps,這個(gè)定義比較簡(jiǎn)單,將 action 作為 props 綁定到組件上,展開helloWorldActions,顯然它已經(jīng)將actions中的changeText綁定到了props上面

'
此時(shí),假如修改actions中的代碼如下
import { CHANGE_TEXT } from '../actionsType'
export function changeText(text) {
return {
type: CHANGE_TEXT,
payload: text
}
}
export function changeTextTest(text) {
return {
type: CHANGE_TEXT,
payload: text
}
}
再看看截圖

很明顯新增的changeTextTest已經(jīng)自動(dòng)綁定到props上
綜上所述,其實(shí)connect可以理解成自動(dòng)封裝了如何將state和actions綁定到組件上的一套邏輯,這下應(yīng)該明白了吧
5.reducers
首先,reducer有一個(gè)拆分的概念,可以將許多的reducer拆分成不同的文件,再通過combineReducers這個(gè)方法來進(jìn)行合并就行了,具體看一下代碼
import { combineReducers } from 'redux'
import helloWorld from './helloWorld'
import student from './student'
const todoApp = combineReducers({
helloChan:helloWorld,
student
})
export default todoApp;
有helloworld和student兩個(gè)reducer,可以通過combineReducers來合并,此時(shí)如果在connect中綁定state時(shí)直接這么寫
const mapStateToProps = state => {
return state
}
我們來看看結(jié)果:

看到了吧,多了student這個(gè)對(duì)象,其實(shí)一般情況下,一個(gè)container對(duì)應(yīng)一個(gè)reducer,所以改改綁定的代碼,如下
const mapStateToProps = state => {
return { helloChan: state.helloChan }
}
再來看看結(jié)果,已經(jīng)沒有student了

好了,本文就講到這里,看完整個(gè)教程,應(yīng)該比較清晰了。