zoukankan      html  css  js  c++  java
  • [React]Redux初探

    来源:
    Redux入门教程-阮一峰
    文档:
    Redux中文文档

    基本概念

    Store

    Store是Redux保存数据的地方,一个应用只能有一个Store;
    生成:

    import {createStore} from 'redux'
    const store=createStore(fn);
    

    使用createStore()来接收另一个函数作为参数生成Store对象,这个参数是Reducer;它也可以接收另一个参数,这个参数将会表示State的最初状态;

    let store = createStore(todoApp, window.STATE_FROM_SERVER)
    

    在上面的例子中,window.STATE_FROM_SERVER将会是状态初始值,如果提供了这个参数,Reducer的默认初始值将会被覆盖。

    State

    State是Store的一份快照,它是在一个时刻的时候的Store.
    当前时刻的State使用store.getState()获得

    import {createStore} from 'redux'
    const store=createStore(fn);
    const state=store.getState();
    

    State与视图层View绑定,两者相关。

    Action

    State的变化由View导致,Action是View发出的通知,表示使State发生变化。
    Action是一个对象,其中只有type属性是必须设置的。

    const action={
        type:"ADD",
        payload:"Learn Redux",
    }
    

    上述Action的名称为type属性,携带的信息为payload的值。

    Action Create

    Action Creator用来生成Action

    const todoSomething="ADD";
    function addTodo(payload){
        return {
            type:todoSomething,
            payload
    }
    }
    const action=addTodo("Learn Redux")
    

    事实上,这里的action和上一个例子的action相同的。
    addTodo函数为一个Action Creator

    store.dispatch()

    store.dispatch()是View发出Action的唯一方法;

    import {createStore} from 'redux'
    const store=createStore(fn);
    
    store.dispatch({
        type:"ADD",
        payload:"Learn Redux"
    })
    

    在上面的例子里,store.dispatch()接收了一个Action作为参数。
    使用store.Create后,可以将代码改写为:

    store.dispatch(addTodo('Learn Redux'));
    

    Reducer

    Store接收到Action之后,将会使用Reducer来使State发生变化,进而影响到View。
    Reducer是一个函数,它接收Action和State作为参数,返回一个新的State

    const reducer=function (state,action){
        //...
        return newState;
    }
    

    我们可能会需要一个State的初始状态,这个时候,我们可以使用:

    const defaultState=0;
    const reducer=(state=defaultState,action)=>{
        switch(action.type){
            case "ADD":
                return state+action.payload;
            default:
                return state;    
    }
    };
    const state=reducer(1,{
        type:"ADD",
        payload:2
    })
    

    在上面的代码中,reducer在接收到名称为ADD的Action后,将State的值进行处理并返回相加的值。

    在实际运行时,Reducer不需要手动调用,store.dispatch()将会自动触发Reducer执行。
    为了使得Reducer自动执行,Store需要知道Reducer,所以在Store生成时,将Reducer作为参数传入createStore();
    Reducer必须是一个纯函数,所以请使用以下写法:

    //State是一个对象时
    function reducer(state,action){
        return Object.assign({},state,{thingToChange});
        //or
        return {...state,...newState};
    }
    //State是一个数组时
    function reducer(state,action){
        return[...state,newItem];
    }
    

    Object.assign()将会将对象进行合并,关于该函数的详细知识,请看这里
    值得注意的是,在任何时候State都不应该发生改变,即一个时刻对应一个新的State,对应一个新的View,不应该试图对State进行改变。

    reducer的拆分

    在state变得巨大的时候,Reducer也会随之变大,可以使用combineReducers方法将不同的Reducer子函数进行合并为一个大函数。

    import { combineReducers } from 'redux';
    
    const chatReducer = combineReducers({
      chatLog,
      statusMessage,
      userName
    })
    
    export default todoApp;
    

    这种写法有一个前提:State的属性名字需要与Reducer的子函数同名,否则采用以下写法:

    const reducer = combineReducers({
      a: doSomethingWithA,
      b: processB,
      c: c
    })
    
    // 等同于
    function reducer(state = {}, action) {
      return {
        a: doSomethingWithA(state.a, action),
        b: processB(state.b, action),
        c: c(state.c, action)
      }
    }
    

    store.subscribe()

    import { createStore } from 'redux';
    const store = createStore(reducer);
    
    store.subscribe(listener);
    

    Store使用该方法设置监听函数,在State发生变化的时候将会自动执行。
    在通常情况下,要将View的更新函数作为在listenr中,对于react,这将会是对state的更新做出反应的函数,如setState()或者是render()
    store.subscribe()将会返回一个函数,调用这个函数就可以解除监听。

    一个实例

    这个实例中,希望实现一个面包屑,这个面包屑的显示将会随着路由的变化发生变化。

    //store.js
    import {createStore} from 'redux'
    import reducer from '../reducer'
    const default={
        menuName:"首页"
    }
    //创建store,初始值为default
    const configStore=createStore(reducer,default);
    
    //reducer.js
    import {type} from '../action'
    //创建Reducer:Data,如果Action的type是"SWITCH_MENU",将会对menuName进行修改
    const Data=(state,action)=>{
        switch(action.type){
            case "SWITCH_MENU":
                return {
                    ...state,
                    menuName:action.menuName
                };
            default:
                return {...state};
    }
    };
    export default Data;
    
    //action
    export function switchMenu(menuName){
           return{
                type:"SWITCH_MENU",
                menuName
    }
    }
    

    以上,redux的基本功能已经完成,store存储数据,reducer将会对action进行响应。

  • 相关阅读:
    IO 单个文件的多线程拷贝
    day30 进程 同步 异步 阻塞 非阻塞 并发 并行 创建进程 守护进程 僵尸进程与孤儿进程 互斥锁
    day31 进程间通讯,线程
    d29天 上传电影练习 UDP使用 ScketServer模块
    d28 scoket套接字 struct模块
    d27网络编程
    d24 反射,元类
    d23 多态,oop中常用的内置函数 类中常用内置函数
    d22 封装 property装饰器 接口 抽象类 鸭子类型
    d21天 继承
  • 原文地址:https://www.cnblogs.com/liuju/p/12639479.html
Copyright © 2011-2022 走看看