一、redux应用

redux应用和之前的useReducer应用比拟相似(详情请看 重学react——context/reducer 一文)

// store.tsimport { createStore, applyMiddleware, combineReducers } from 'redux';import logger from 'redux-logger'; // 中间件import thunk from 'redux-thunk'; // 中间件export interface IState {    name: string,    age: number,    sons: any[]}export const state: IState = {    name: 'lihaixing',    age: 32,    sons: []};export type Action = {    type?: string;    data?: any;};export function reducer(state: IState | undefined, action: Action) {    if (!action.type && !action.data) {        return {            ...state,            ...action        };    }    switch (action.type) {        case 'update':            return {                ...state,                ...action.data            };        default:            return state;    }}// createStore与useReducer相似export const store = createStore(reducer, state, applyMiddleware(logger, thunk));
// contaner.tsximport React, { useReducer } from 'react';// react-redux的作用和react的context相似import {Provider} from 'react-redux'; import { store } from './store';import Com1 from './comp1'import Com2 from './comp2'const IndexView = () => {    return <Provider store={store}>        <Com1 />        <Com2 />    </Provider>};export default IndexView;
// com1.tsximport React, { useContext } from 'react';import { IState } from './index';// connect和useContext的作用相似import { connect } from 'react-redux';const IndexView = (props: any) => {    const {name, age, sons} = props.state;    const {update, asyncUpdate} = props;    const setAge = () => {        // dispatch({type: 'update', data: {age: age + 1}});        update({age: age + 1});    };    const setSons = () => {        // setTimeout(()=>{        //     update({sons: [...sons, 1]});        // })        asyncUpdate({sons: [...sons, 1]});    };    return <div>        {name} <br/>        {age} <br/>        {sons} <br/>        <button onClick={setAge}>按钮age</button>        <button onClick={setSons}>按钮sons</button>    </div>;};const mapStateToProps = (state: IState) => ({state});const mapDispatchToProps = {    update: (data: any) => ({type: 'update', data}),    // 异步返回的是函数    asyncUpdate: (data: any) => (dispatch: any) => {        setTimeout(() => {            dispatch({type: 'update', data});        },1000);    }};// 不传第二个参数,props会有dispatchexport default connect(mapStateToProps, mapDispatchToProps)(IndexView);

从上述咱们能够将redux和useReducer/useContext作比照
重学react——context/reducer

二、手写Redux

1、createStore

export function createStore(reducer: any, state: any, enhancer?: any) {    if (!!enhancer) {        return enhancer(createStore)(reducer, state);    }    let currentState: any = state;    const currentListener: any[] = [];    function getState() {        return currentState;    }    function dispatch(action: any) {        currentState = reducer(currentState, action);        currentListener.forEach((v) => v());        return action;    }    function subscribe(cb: any) {        currentListener.push(cb);    }    return {        getState,        dispatch,        subscribe    };}

2、中间件

export function applyMiddleware(...middlewares: any) {    return (createStore: any) => {        return (reducer: any, state: any) => {            const store = createStore(reducer, state);            let dispatch = store.dispatch;            const midApi = {                getState: store.getState,                dispatch: (...arg: any) => dispatch(...arg)            };            /**             * 太难了,写不上来了             * @type {any[]}             */            const chains = middlewares.map((mw: any) => mw(midApi));            // 强化dispatch 按程序执行            dispatch = compose(...chains)(dispatch);            console.log(dispatch)            return {                ...store,                dispatch            };        };    };}// 聚合函数 f3(f2(f1(arg)))// const f1=(x)=>x;// const f2=(x)=>2*x;// const f3=(x)=>3*x;export function compose(...funcs: any) {    if (funcs.length === 1) {        return funcs[0];    }    return funcs.reduce((left: any, right: any) => (...args: any) => right(left(...args)));}
// 本人写一个中间件function logger({getState, dispatch}: { getState: any, dispatch: any }) {    return (dispatch: any) => (action: any) => {        console.log(action.type + '执行了');        return dispatch(action);    };}function thunk({getState, dispatch}: { getState: any, dispatch: any }) {    return (dispatch: any) => (action: any) => {        if (typeof action === 'function') {            return action(dispatch, getState);        }        return dispatch(action);    };}