zoukankan      html  css  js  c++  java
  • React技术栈——Redux

    Redux

    1.Redux是什么?

      Redux对于JavaScript应用而言是一个可预测状态的容器。换言之,它是一个应用数据流框架,而不是传统的像underscore.js或者AngularJs那样的库或者框架。
      Redux最主要是用作应用状态的管理。简言之,Redux用一个单独的常量状态树(对象)保存这一整个应用的状态,这个对象不能直接被改变。当一些数据变化了,一个新的对象就会被创建(使用actions和reducers)。

    2.核心概念

    • actions
      actions就是事件。actions传递数据给store,store获取来自actions的信息。actions内部就只是简单的具有一个type属性(通常是变量)的js对象,这个对象描述了actions的类型以及传递给store的信息。
    • reducers
      reducers是一些纯函数,它通过获取当前的state和一个action作为参数,再返回下一个state。简单来说,就是根据不同的action来完成state的变化。
    • store
      store对象保存应用的状态并提供一些帮助方法来存取状态,派发状态以及监听状态。全部的state由一个store表示,所有的action通过reducer返回一个新的状态对象。这使得Redux变得非常简单以及可预测。

    3.Redux的基本使用

    (1) 创建store

    Redux的核心是store,Redux只是提供了规则和API,store的创建需要我们来完成,只有创建完store,才能够使用。
    创建store,就要使用createStore方法。使用createStore方法时,需要涉及以下几个内容:

    • state
    • action
    • reducer

    以做一个计数器为例。
    首先,要先定义一个初始的state,如下:

    const initState = {  
        count:520
    }
    复制代码

    然后,定义两个action对象,如下:

    <!--定义增加的action-->
    const increment = {
        type:"INCREMENT"
    }
    <!--定义减少的action-->
    const decrement = {
        type:"DECREMENT"
    }
    复制代码

    最后,编写reducer函数,如下:

    <!--定义一个reducer,根据不同action中的type属性,去完成对state的状态更新-->
    function reducer (state=initState,action){
        switch (action.type){
            case "ICREMENT":
                return {count:state.count+1};
            case "DECREMENT":
                return {count:state.count-1};
            default:
                return state;
        }
    }
    复制代码

    当我们定义完reducer之后,就可以使用createStore方法创建store对象了,如下:

    <!--创建store对象-->
    const store = Redux.createStore(reducer)
    复制代码

    (2) 使用store

    创建完store对象后,我们该怎么使用store呢?
    store有如下几个API:

    • getState:用于获取状态
    • dispatch:用于派发状态
    • subscribe:用于监听状态,一旦状态发生变化们,就会执行回调函数

    使用如下:

    <!--创建store对象-->
    const store = Redux.createStore(reducer)
    console.log(store.getState())
    复制代码
    <!--监听状态的变化-->
    store.subscribe(()=>{
      console.log("现在的状态是",store.getState())  
    })
    复制代码
    <!--通过dispatch来触发action对状态state的修改  -->
    store.dispatch(increment)
    store.dispatch(decrement)
    复制代码

    其实,action对象中还可以有其他的属性,从而实现对state值的修改,可以使用action creators函数来生成action,在函数内定义一个参数,就可以根据需求来修改state的值了,如下:

    <!--用action creators函数创建增加的action-->
    function increment(step) {
        return{
            type:"INCREMENT",
            step
        }
    }
    复制代码
    <!--用action creators函数创建减少的action-->
    function decrement(step) {
        return{
            type:"DECREMENT",
            step
        }
    }
    复制代码

    接着要修改reducer,如下:

    <!--定义一个reducer,根据不同action中的type属性,去完成对state的状态更新-->
    function reducer (state=initState,action){
        switch (action.type){
            case "ICREMENT":
                return {count:state.count+action.step};
            case "DECREMENT":
                return {count:state.count-action.step};
            default:
                return state;
        }
    }
    复制代码

    最后要在dispatch方法上调用,可以通过改变实参来实现想要的需求,如下:

    store.dispatch(increment(1));
    store.dispatch(increment(2));
    store.dispatch(increment(3));
    复制代码

    (3) store的应用

    由于Reducer是纯函数,所以Reducer函数中不能改变state,必须返回一个全新的对象,但是像在todosMVC案例中需要添加todo的方法要怎么来实现呢?
    在Reducer函数中,不能改变state,因此todos这个数组就不能使用数组的方法了,应该使用对象的合并操作(Object.assign()).下面就使用Redux来实现todosMVC案例中的几个功能:

    第一步,规划state,如下:

    <!--初始化state-->
    const initState = {
        todos:[
        {content:"html",complete:false},
        {content:"css",complete:false},
        {content:"js",complete:false},
        ],
        visibility:"all"
    }
    复制代码

    第二步,定义action,使用action creators来创建,如下:

    <!--定义action creators-->
    <!--添加todo-->
    function addTodo(content){
        return{
            type:"ADD_TODO",
            content
        }
    }
    <!--设置todo的可见性-->
    function setVisibility(filter){
        return{
            type:"SET_VISIBLLITY",
            filter
        }
    }
    复制代码

    第三步,定义reducer,如下:

    <!--定义reducer-->
    function reducer(state=initState,action){
        switch(action.type){
            case "ADD_TODO":
                var todos = [...state.todos,{content:action.content,done:false}]
                return Object.assign({},state,{todos})
            case "SET_VISIBILITY":
                return Object.assign({},state,{visibility:action.filter})
            default:
                return state;
        }
    }
    复制代码

    第四步,创建store对象,如下:

    <!--创建store对象-->
    const store = Redux.createStore(reducer);
    复制代码

    第五步,使用store,如下:

    <!--使用store-->
    console.log(store.getState())
    复制代码

    (4)reducer的拆分与合并

    如果是在真实的项目中,就会有很多的状态要管理,因此就可以分开定义reducer来处理各自的状态。reducer的拆分如下:

    <!--定义todos状态的reducer-->
    function todos(state=[],action){
        switch (action.type){
            case "ADD_TODO":
                return [...state,{content:action.content,complete:false}];
            default:
                return state;
        }
    }
    复制代码
    <!--定义visibility对应的reducer-->
    function visibility(state="all",action){
        switch (action.type){
            case "SET_VISIBILITY":
                return action.filter;
            default:
                return state;
        }
    }
    复制代码

    然后合并两个reducer,如下:

    function reducer (state=initState,action){
        return{
            todos:todos(state.todos.action),
            visibility:visibility(state.visibility.action)
        }
    }
    复制代码

    还可以使用Redux提供的combineReducers方法,如下:

    const reducer = Redux.combineReducers({
        todos,
        visibility
    })
    复制代码

    总结

      Redux是一个JavaScript库,用于管理应用的前端状态。Redux并非React应用的必须条件,但是随着网络应用的复杂性越来越高,状态管理不当可能会导致bug。Redux应用中的全局状态存储在单一数据源store中。因为状态的更新受到严格控制,使得Redux非常具有可预测性。实际上,开发人员喜欢Redux的主要原因之一就是它的可预测性。

    转载于:https://juejin.im/post/5b77ce166fb9a019f1800001

  • 相关阅读:
    bzoj1257 [CQOI2007]余数之和sum
    bzoj1053 [HAOI2007]反素数ant
    bzoj3680 吊打XXX
    CodeVS1344 线型网络
    bzoj1925 [Sdoi2010]地精部落
    2016年北大高代考研题解答
    巴塞尔问题(Basel problem)的多种解法
    积分计算题
    PDF添加水印的办法
    Matlab技巧1:在同一坐标系上绘制两个函数图像
  • 原文地址:https://www.cnblogs.com/twodog/p/12136183.html
Copyright © 2011-2022 走看看