Redux之旅-1

时间:2016.4.7-17:24
做者:三月懒驴
入门配置文章:连接javascript

准备

在你的项目下面加入redux / react-redux前端

npm install redux --save
    npm install react-redux --save

入门小例子

网上有不少关于Redux的解析了,我也不从抽象化去讲解整个redux的做用,而发现讲解Redux的编程化例子其实不多,因此在这里用代码来讲明一下。什么叫作redux,以及它的Action/reducer/storejava

看过我上一遍项目环境搭建的朋友应该有一个基本的项目目录架构。react

主要写代码的仍是在app这个文件夹里面,里面的目录分布npm

- component -->放置组件的
   - redux     -->放置action && reducer
   - redux_lesson -->目前是放置用Provider打包出来的组件
   - main.js   -->程序入口

代码开始前的思考

咱们如今要作一个很简单的东西,用前端的话来讲就是一个div标签,里面放置一个数字0,当咱们点击这个div的时候,里面的数字就递增。这里面咱们要进行一步就是,写代码前的思考。
如上所说,咱们的需求就是:点击,数字递增。那么咱们的一些参数应该定义出来了。编程

改变View的数据—state

我的简单理解的state就是能够反映到view上的可变数据,这里咱们的state定义以下redux

state = {count:0}

改变state的钥匙—Action

一样是我的理解:state是可变的,但不是随便的可变,要改变它,就须要一把钥匙去打开这道大门,而action就是这把钥匙了
咱们把这个action定义成以下:segmentfault

increaseAction = {type:'increase'}

Action 本质上是 JavaScript普通对象。咱们约定,action内使用一个字符串类型的 type字段来表示将要执行的动做。多数状况下,type 会被定义成字符串常量。架构

改变state的动做—Reducer

我的的胡乱理解:有了state,有了要改变state的钥匙Action,那么谁来进行改变state的操做?reducer就是这么一个加工车间,你拿着原料(state)和钥匙(Action)进去总车间,用钥匙(Action)打开对应的生产线,生产出来新的产品(也是state)回去app

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)

相关文章
相关标签/搜索