资讯专栏INFORMATION COLUMN

Redux之旅-1

hiyang / 1745人阅读

摘要:我们约定,内使用一个字符串类型的字段来表示将要执行的动作。多数情况下,会被定义成字符串常量。要进去工厂加工产品,就得带上相应得钥匙,不同的钥匙对应工厂中上不同的生产线里面的函数,从而有不同的产出改变之后的

时间: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 
    }
}

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 
{count}
} } //样式文件,不用细看 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 
    }
}

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 
{count}
} } //样式文件,不用细看 ...(以下相同就略去)
结语

redux其实不难理解,按照我个人理解的加工工厂模式:有一家大公司叫做store,里面有工厂(reducer),公司(store)只有一家,但这家公司(store)可以有很多工厂(reducer)。要进去工厂加工产品(state),就得带上相应得钥匙(Action),不同的钥匙(Action)对应工厂中上不同的生产线(redecer里面的switch函数),从而有不同的产出(改变之后的state)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79125.html

相关文章

  • Redux之旅-2

    摘要:之旅时间作者三月懒驴入门配置文章链接之旅链接前言上一篇文章,很简单的用代码来说明了,,,各自的意义和相互的联系以及在实际开发的应用。分割你的,使每一个更有意义,之后再合并回来。分割和合并和不同。的只有一个只有一个就意味着只有一个。 Redux之旅-2 时间:2016.4.22-11:24作者:三月懒驴入门配置文章:链接Redux之旅-1:链接 1. 前言 上一篇文章,很简单的用代码来说...

    liangzai_cool 评论0 收藏0
  • MobX学习之旅

    摘要:一其实是一个比较轻便的可扩展的状态管理工具,是一个由以及一些其他团队的人共同维护的开源项目。当应用公共状态的组件在状态发生变化的时候,会自动完成与状态相关的所有事情,例如自动更新自动缓存数据,自动通知等。 一、MobX MobX其实是一个比较轻便的可扩展的状态管理工具,是一个由Facebook以及一些其他团队的人共同维护的开源项目。 当应用公共状态的组件在状态发生变化的时候,会自动完...

    刘福 评论0 收藏0
  • [译]看这些文章,足够你学好redux

    摘要:原文地址我想分享一些文章,来帮你学习的概念和架构在开始之前我们先来看这两篇文章,用代替和然后我们通过一个代码教程我翻译地址深入了解,然后看一看超级介绍完成你对的探索之旅现在是时候去学习和再往前走理解并且看一看关于的一切注尽量中文地址的我用的 原文地址 我想分享一些文章,来帮你学习redux的概念和架构 在开始redux之前我们先来看这两篇文章,用High Order Component...

    fengxiuping 评论0 收藏0
  • 滚蛋吧!constant 君

    摘要:引入,有效解决事件分发时,事件类型的一致性以及清晰逻辑性。其实,细心思考,不难发现,随着项目增大。目录将会随着数据处理事件迅速膨胀。大家一直维护着这个事件命名机制,身心疲惫有木有。其实,随着项目增大,独立出来的也会导致非常麻烦的维护问题。 作者:Jogis原文链接:https://github.com/yesvods/Blog/issues/4转载请注明原文链接以及作者信息 前言 事情...

    huangjinnan 评论0 收藏0
  • 滚蛋吧!constant 君

    摘要:引入,有效解决事件分发时,事件类型的一致性以及清晰逻辑性。其实,细心思考,不难发现,随着项目增大。目录将会随着数据处理事件迅速膨胀。大家一直维护着这个事件命名机制,身心疲惫有木有。其实,随着项目增大,独立出来的也会导致非常麻烦的维护问题。 作者:Jogis原文链接:https://github.com/yesvods/Blog/issues/4转载请注明原文链接以及作者信息 前言 事情...

    ideaa 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<