时刻:2016.4.7-17:24
作者:三月懒驴
入门设置文章:链接
预备
在你的项目下面到场redux / react-redux
npm install redux --save
npm install react-redux --save
入门小例子
网上有许多关于Redux的剖析了,我也不从抽象化去解说全部redux的作用,而发明解说Redux的编程化例子实在很少,所以在这里用代码来申明一下。什么叫做redux,以及它的Action/reducer/store
看过我上一遍项目环境搭建的朋侪应当有一个基础的项目目次架构。
主要写代码的照样在app这个文件夹内里,内里的目次散布
- component -->安排组件的
- redux -->安排action && reducer
- redux_lesson -->如今是安排用Provider打包出来的组件
- main.js -->顺序进口
代码最先前的思索
我们如今要做一个很简朴的东西,用前端的话来讲就是一个div标签,内里安排一个数字0,当我们点击这个div的时刻,内里的数字就递增。这内里我们要举行一步就是,写代码前的思索。
如上所说,我们的需求就是:点击,数字递增。那末我们的一些参数应当定义出来了。
转变View的数据—state
个人简朴明白的state就是能够反应到view上的可变数据,这里我们的state定义以下
state = {count:0}
转变state的钥匙—Action
同样是个人明白:state是可变的,但不是随意的可变,要转变它,就须要一把钥匙去翻开这道大门,而action就是这把钥匙了
我们把这个action定义成以下:
increaseAction = {type:'increase'}
Action 本质上是 JavaScript一般对象。我们商定,action内运用一个字符串范例的 type字段来示意将要实行的行动。多半情况下,type 会被定义成字符串常量。
转变state的行动—Reducer
个人的胡乱明白:有了state,有了要转变state的钥匙Action,那末谁来举行转变state的操纵?reducer就是这么一个加工车间,你拿着质料(state)和钥匙(Action)进去总车间,用钥匙(Action)翻开对应的临盆线,临盆出来新的产物(也是state)归去
let reducer = (state={count:0},action)=>{
//这内里通报进来两个参数,
//一个是我们前面定义的state,假如木有传入的话,就用{count:0}
//一个是我们前面定义的action,下面就要搜检它的type来肯定操纵
let count = state.count
switch(action.type){
//假如钥匙插对了孔,我们就返回举行了响应操纵后的state对象
case 'increase':
return {count:count+1}
break
//假如钥匙都不对,就返回没操纵过的state
default:
return state
}
}
被我吃了的store
由于相对前面三个东西来讲,store是在太轻易明白了,引入官方的话:
Store 就是把它们联系到一同的对象。Redux 运用只要一个单一的 store。当须要拆分处置惩罚数据的逻辑时,运用 reducer 组合 而不是建立多个 store。
最先真正写代码了
实在上面的步骤我们都把一个redux处置惩罚数据的相干事变做的差不多了,那末接下来就是要真正的去写成顺序
建立action
文件位置: app/redux/action.js
export const increaseAction = {type:'increase'}
建立reducer
文件位置: app/redux/reudcer.js
let reducer = (state={count:0},action)=>{
let count = state.count
switch(action.type){
case 'increase':
return {count:count+1}
break
default:
return state
}
}
export default reducer
天生store,打包出新组件
主要的事变:store只要一个!
文件位置: app/redux_lesson/lesson_0.js
'use strict'
import React from 'react'
import { createStore } from 'redux'
import { Provider,connect } from 'react-redux'
//这个index.js文件会在鄙人一步建立
import Index from '../component/index'
import reducers from '../redux/reducer'
//建立store
let store = createStore(reducers)
/*
mapStateToProps你能够明白成鄙人面connect的时刻为组件供应一个props,这个props的值是redux的state
*/
let mapStateToProps = (state) =>{
return {count:state.count}
}
//衔接你的state和最外层的组件
let Content = connect(mapStateToProps)(Index)
let {Component} = React
//运用Provider来把新的App组件打包出来
class App extends Component{
render(){
return <Provider store={store}><Content /></Provider>
}
}
export default App
建立View
在View内里我们会接受到两个props。一个是在mapStateToProps天生的state,一个是store给我们的dispatch,这是是一个函数,我们用它的要领很简朴粗犷,往内里传入一个Action就好了,它接受了这个Action就会通知reducer去实行。
文件位置: app/compoment/index.js
'use strict'
import React from 'react'
import { connect } from 'react-redux'
//请注重这内里引入了action
import {increaseAction} from '../redux/action'
let {Component,PropTypes} = React
class Index extends Component{
//这一步是搜检传入的各个prop范例是不是准确
ProTypes = {
count:PropTypes.number.isRequired,
}
constructor(props){
super(props)
}
handleClick(){
/*
这一步输入this.props能够看到,实在内里有两个东西
鄙人面的render内里我们用到了this.props.count这个
那末这里我们要用到dispatch
*/
console.log(this.props)
let {dispatch} = this.props
//粗犷简朴的运用
dispatch(increaseAction)
}
render(){
let {count} = this.props
return <div onClick = {this.handleClick.bind(this)} style={styles.circle}>{count}</div>
}
}
//款式文件,不必细看
let styles = {
circle:{
width:'100px',
height:'100px',
position:'absolute',
left:'50%',
top:'50%',
margin:'-50px 0 0 -5px',
borderRadius:'50px',
fontSize:'60px',
color:'#545454',
backgroundColor:'#fcfcfc',
lineHeight:'100px',
textAlign:'center',
}
}
export default Index
进一步优化代码
要做一个点击递增就须要那末多步骤是不是是很懊恼?然则假如项目大起来以后,你想像如许,你就能够建立差别的钥匙Action,再编写差别的临盆线reducer来修正各自的state,然则如上所做,我们的逻辑代码(点击递增)和View照样绑缚在一同(就是在组件内里运用dispatch)这个要领是不可取的。所以下一步我们就要进一步优化我们的代码
文件位置: app/redux_lesson/lesson_0.js
'use strict'
import React from 'react'
import { createStore } from 'redux'
import { Provider,connect } from 'react-redux'
import Index from '../component/index'
import reducers from '../redux/reducer'
/*
注重:这里是新增的
相对本来,我们在最外层打包这里引入Action
*/
import {increaseAction} from '../redux/action'
//建立store
let store = createStore(reducers)
/*
mapStateToProps你能够明白成鄙人面connect的时刻供应一个state
*/
let mapStateToProps = (state) =>{
return {count:state.count}
}
/*
注重:这里是新增的
mapDispatchToProps你能够明白成鄙人面connect的时刻供应一个安排好钥匙的函数onIncreaseClick,直接挪用就能够去reducer修正state了
*/
let mapDispatchToProps = (dispatch) =>{
return{onIncreaseClick:()=>dispatch(increaseAction)}
}
/*
注重:这里是修正了的
衔接你的state和最外层的组件
*/
let Content = connect(mapStateToProps,mapDispatchToProps)(Index)
let {Component} = React
//运用Provider来把新的App组件打包出来
class App extends Component{
render(){
return <Provider store={store}><Content /></Provider>
}
}
export default App
文件位置: app/compoment/index.js
'use strict'
import React from 'react'
import { connect } from 'react-redux'
/*
注重:这里是修正乐的
如今不必引入action了,由于前一步已把钥匙Action放到响应的函数中去,作为props传入组件内里
*/
//import {increaseAction} from '../redux/action'
let {Component,PropTypes} = React
class Index extends Component{
//这一步是搜检传入的各个prop范例是不是准确
ProTypes = {
count:PropTypes.number.isRequired,
onIncreaseClick:PropTypes.func.isRequired,
}
constructor(props){
super(props)
}
handleClick(){
/*
注重:这里是修正过的
如今,我们把打包好的,带着钥匙的函数举行挪用
*/
console.log(this.props)
let {onIncreaseClick} = this.props
onIncreaseClick()
}
render(){
let {count} = this.props
return <div onClick = {this.handleClick.bind(this)} style={styles.circle}>{count}</div>
}
}
//款式文件,不必细看
...(以下雷同就略去)
结语
redux实在不难明白,根据我个人明白的加工工场形式:有一家大公司叫做store,内里有工场(reducer),公司(store)只要一家,但这家公司(store)能够有许多工场(reducer)。要进去工场加工产物(state),就得带上响应得钥匙(Action),差别的钥匙(Action)对应工场中上差别的临盆线(redecer内里的switch函数),从而有差别的产出(转变以后的state)