zoukankan      html  css  js  c++  java
  • Redux基础

    const Redux = require('redux');
    
    const reducer = function(state, action) {
        if (action.type === 'changeName') {
            // const newState = JSON.parse(JSON.stringify(state));
         // 不能直接修改原来的state对象
    return Object.assign({}, state, {name: action.name}); } else { // 未配置情况,返回原来的state return state; } } // 参数: reducer(return state), [init state] const store = Redux.createStore(reducer, {name: 'init name', age: 20}); // 订阅监听 store.subscribe(() => console.log(store.getState())); // 同步dispatch const action = {
      changeName() {
        return {   type:
    'changeName',   name: 'lily'
        }
      },
      increment (number) {
          return {
            type: "increment",
            data: number
          }
        }
      }
     store.dispatch(action);

    redux中, Redux API主要有:

    1. createStore()

    2. applyMiddleware()

    3. combineReducers()

    // combineReducers 实现原理
    // 将各个reducer函数包裹在一个对象中,最后通过生成一个新reducer函数 
    // function combineReducers(reducers) {
    //     return function reducer(state, action) {
    //         let newState = {};
    //         for (let key in reducers) {
    //           把state中每一个属性值作为state,带入对应的Reducer中进行处理
    //             newState[key] = reducers[key](state[key],action);
    //         }
    //     }
    // }
    const Redux = require('redux');
    
    // const state = { a: [], b: [], c:{ name: '', group: []} };
    
    const aReducer = function(state, action) {
        if (typeof state === 'undefined') return [];
        switch (action.type) {
            case 'a':
                return state.concat([action.data]);
            default:
                return state;
        }
    }
    
    const bReducer = function(state, action) {
        if (typeof state === 'undefined') return [];
        switch (action.type) {
            case 'b':
                return state.concat([action.data]);
            default:
                return state;
        }
    }
    
    const cNameReducer = function(state, action) {
        if (typeof state == 'undefined') return '';
        switch (action.type) {
            case 'c':
                return action.name;
            default:
                return state;       
        }
    }
    
    const cGroupReducer = function(state, action) {
        // state对应的是group的value
        if (typeof state === 'undefined') return [];
        switch(action.type) {
            case 'c':
                return state.concat(action.item);
            default:
                return state;
        }
    }
    
    const cReducer = function (state, action) {
        // state对应的是c的value
        if (typeof state === 'undefined') return {name: '', group: []};
        switch(action.type) {
            case 'c':
                // 返回reducer处理函数,然后调用
                return Redux.combineReducers({name: cNameReducer, group: cGroupReducer})(state, action); 
            default:
                return state;
        }
    }
    // 每个属性对应的reducer
    const reducers = Redux.combineReducers({a: aReducer, b: bReducer, c: cReducer});
    const store = Redux.createStore(reducers, {a: [111], b: [222], c:{ name: 'hi', group:[] }});
    
    store.subscribe(() => console.log(store.getState()));
    
    const action1 = {
        type: 'b',
        data: 'lead'
    };
    const action2 = {
        type: 'a',
        data: 'tail'
    }
    const action3 = {
        type: 'c',
        name: 'jkp',
        item: 'pp'
    }
    store.dispatch(action1);
    store.dispatch(action2);
    store.dispatch(action3);

    store API包括以下几个:

    1. getState()

    2. subscribe(callback)

    3. dispatch(action)

    Redux默认只支持同步action[返回对象](即:dispatch本身只能进行同步触发),若要实现异步action,需要借助一些特殊的插件,如redux-thunk,redux-promise。

    let action = {
    // 同步action,返回一个对象
      increment (number) {
        return {
          type: "increment",
          data: number
        }
      },
    
    // 异步action, 返回一个函数
      asyncIncrement (number) {
        return dispatch => {
          // 函数内部执行异步操作
          setTimeout(() => {
          // dispatch一个同部的action对象
            dispatch({
              type: "increment",
              data: number
            })
          }, 1000);
        }
      },
    }

    与此同时,在createStore()加入第二个参数--中间件 Redux.applyMiddleware(xxx)

    const thunk = require("redux-thunk").default;
    
    const store = Redux.createStore(reducer, Redux.applyMiddleware(thunk));

    这里提一下‘redux-thunk'这个中间件的使用[转自:https://juejin.im/post/6844903505199628301]

        import { createStore, applyMiddleware } from 'redux';
        import thunk from 'redux-thunk';
        import rootReducer from './reducers/index';
        //注册thunk到applyMiddleware
        const createStoreWithMiddleware = applyMiddleware(
          thunk
        )(createStore);
        
        const store = createStoreWithMiddleware(rootReducer);
        
        //action方法
        function increment() {
          return {
            type: INCREMENT_COUNTER
          };
        }
        //执行一个异步的dispatch
        function incrementAsync() {
          return dispatch => {
            setTimeout(() => {
              dispatch(increment());
            }, 1000);
          };
        }

    源码分析

    // thunk-redux 源码
        function createThunkMiddleware(extraArgument) {
         // 将dispatch和getState传入action,next()和action()是redux提供的方法。
          return ({ dispatch, getState }) => next => action => {
           // 接着做判断,如果action是一个function,就返回action(dispatch, getState, extraArgument),否则返回next(action)
            if (typeof action === 'function') {
              return action(dispatch, getState, extraArgument);
            }
        
            return next(action);
          };
        }
    const thunk = createThunkMiddleware(); // 给thunk设置一个属性withExtraArgument,并且将createThunkMiddleware整个函数赋给它。 thunk.withExtraArgument = createThunkMiddleware; export default thunk;

    总结:thunk是一个中间函数,它的返回值是一个函数表达式。action里面可能传递多个参数,我们不可能再专门替每个action写一个传递方法。那么就有了thunk的出现,thunk可以将多个参数的函数作为一个参数传递。

    例如有这样一个action

    function test(arg1, arg2, ...) {
          return {
                type: "TEST",
                arg1,
                arg2,
                ...
          }
     }

    然后我们在执行dispatch()方法是,需要把test()的返回值作为参数传递。这样就解决了多参数传递的问题,这个test()就成了一个thunk。

     promise实现异步触发

    // 借助promise实现异步触发
    function callAction() {
        const actionPromise = new Promise((resovle, reject) => {
            const action = {
                type: 'changeName',
                name: 'lily'
            };
            resovle(action);
        })
    
        actionPromise.then((action) => {
            store.dispatch(action);
        })
    }
    callAction();

    PS: redux-devtools下载安装  https://github.com/zalmoxisus/redux-devtools-extension/releases

    然后在项目目录下npm i redux-devtools-extension --save-dev

    import {composeWithDevTools} from 'redux-devtools-extension';
    
    const store = Redux.createStore(reducer, composeWithDevTools(Redux.applyMiddleware(thunk)));
  • 相关阅读:
    Windows 2008server部署pxe启动安装windows系统
    wordpress迁移报错
    解决PHP无法监听9000端口问题/502错误解决办法
    Failed to start LSB: starts php-fpm
    nginx.service: control process exited, code=exited status=1
    linux通过ntp同步时间
    ESXI6.7主机降级至ESXI6.5
    在vCenter Server中添加ESXi 主机失败的问题
    windows ping bat脚本
    不错的网站压力测试工具webbench
  • 原文地址:https://www.cnblogs.com/ceceliahappycoding/p/12388532.html
Copyright © 2011-2022 走看看