动态

详情 返回 返回

Redux - 动态 详情

Redux類適用所有React生態項目

import {
    applyMiddleware,
    combineReducers,
    legacy_createStore as createStore,
    Store,
    compose,
} from "redux";
import thunk from "redux-thunk";
import {connect, Provider} from "react-redux";
import {Action as ReduxAction, AnyAction} from "redux";

type StoreState = {
    [key: string]: string | number | boolean | undefined | null | unknown | void
}

type StoreMap<T = any, S = any> = {
    namespace: string;
    state: S | StoreState;
    reducers?: {
        [key: string]: (state: StoreState, params: T) => StoreState
    },
    [key: string]: any;
}

interface StoreStore<T = any> {
    namespace: string;
    state: T | StoreState;
    
    [key: string]: any;
}


type StoreStores<T = any> = {
    [key: string]: StoreStore<T>;
};

type StoreReducers<T = any> = {
    [key: string]: T
}

interface Dispatch<A extends ReduxAction = AnyAction> {
    <T extends A> (action: T): T
}

type Params = { [key: string]: any }

export default class Redux<T = Params> {
    public static _collection: Params = {};
    public dispatch: Dispatch;
    public namespace: string;
    public state: T = {} as T;
    
    constructor () {
    
    }
    
    // 所有狀態的集合
    public get collection () {
        return Redux._collection;
    };
    
    // 初始化的狀態
    public get store () {
        return {
            namespace: this.namespace,
            state: this.state,
        } as {
            namespace: string;
            state: T
        };
    }
    
    // dispatch
    public get action () {
        return (dispatch: Dispatch) => this._renderRedux(dispatch);
    }
    
    // 狀態改變
    public setState = (state: T, cb?: (newState: T) => void): T => {
        this.dispatch({
            type: `${this.namespace}/setState`,
            state
        });
        const newState = {
            ...this.state,
            ...state
        };
        this.state = newState;
        if (cb) {
            cb(newState);
        }
        Redux._collection[this.namespace] = newState;
        return newState;
    };
    
    // 創建多個狀態
    public createStores (
        stores: StoreStores
    ): Store {
        return createStore(
            combineReducers(
                this._createReducers(
                    {
                        ...stores
                    }
                )
            ), compose(applyMiddleware(thunk)
            )
        );
    }
    
    // 根據每個store創建xxx/setState
    private _createState (map: StoreMap) {
        const newMap = {...map};
        newMap.reducers = newMap.reducers ? newMap.reducers : {};
        const newReducers: StoreReducers = {};
        newReducers[`${newMap["namespace"]}/setState`] = (_state: StoreState, {state}: { state: StoreState }) => ({..._state, ...state});
        newMap.reducers = newReducers;
        return (state = newMap.state, action: { type: string }) => {
            if (newMap.reducers && newMap.reducers[action.type]) {
                return newMap.reducers[action.type](state, action);
            } else {
                return state;
            }
        };
    };
    
    private _createReducers (reducers: StoreStores): StoreReducers {
        return Object.entries(reducers).reduce((preItems, item) => {
            const namespace = item[1].namespace;
            Redux._collection[namespace] = item[1].state;
            return {
                ...preItems,
                [namespace]: this._createState(item[1])
            };
        }, {});
    };
    
    private _renderRedux = (dispatch: Dispatch) => {
        this.dispatch = dispatch;
        return this;
    };
}

export {
    Dispatch,
    StoreMap,
    StoreReducers,
    StoreState,
    StoreStores,
    StoreStore,
    Redux,
    connect,
    Provider,
};

繼承Redux

import Redux from "@/common/redux/redux";
import {homeAction, HomeAction} from "@/common/redux/home";


interface State {
    desc?: string;
    title?: string;
}
// 繼承Redux
export class CommonAction extends Redux<State> {
    private _homeAction: HomeAction;
    
    constructor () {
        super();
        // 這個狀態的名字(必須要有)
        this.namespace = 'common';
        // 需要管理的單個狀態(必須要有)
        this.state = {
            a: '',
            b: '',
        }
    }
    // home類裏的方法在這裏調用
    private get $homeAction () {
        if (this._homeAction) {
            return this._homeAction;
        }
        this._homeAction = homeAction(this.dispatch);
        return this._homeAction;
    }    
    
    public onChange = async () => {
        // 所有狀態的數據 this.collection['common'] = this.state
        this.collection;
        // 當前common狀態
        this.state;
        // 修改common狀態
        this.setState({ a: 1, b: 2 });
        // 修改其他狀態(這裏是home狀態)
        this.dispatch({type: 'home/setState', {c: 3, d: 4}})
    };

   public onChangeHome = () => {
       // 調用home裏的方法
       this.$homeAction.xxxx();
   } 
}

const common = new CommonAction();

export const commonAction = common.action;
export const commonStore = common.store;

把數據放到全局(可以放多個Store)

import React from "react";
import Taro from "@tarojs/taro";
import Redux, {Provider} from "@/common/redux/redux";
// 各個狀態
import {commonStore} from "@/common/redux/common";
import {homeStore} from "@/common/redux/home";



const createStoreChildren = (children) => {
    // 狀態各個註冊
    const stores = React.useRef(new Redux().createStores({
        commonStore,
        homeStore
    })).current;
    return <Provider store={stores}>
        {children}
    </Provider>;
};

// createStoreChildren用來包裹最外層
export default createStoreChildren;

單個頁面或者組件引入使用

...
export default connect((e: {}) => {
    // 把當前頁面或者組件導入用到的狀態值
    return {
        a: e['common'].a,
        b: e['common'].b,
        c: e['home'].c,
        d: e['home'].d,
    };
}, (dispatch) => {
    // 把當前頁面或者組件導入用到的方法
    const home = homeAction(dispatch);
    const common = commonAction(dispatch);
    return {
        dispatch,
        setHomeState: home.setState,
        homeInit: home.homeInit,
        setCommonState: common.setState,
        onChange: common.onChange,
        
    };
})(Index);
user avatar jcguanqi 头像 qian5201314 头像 momeak9 头像 imhaoli 头像 liulhf 头像 minnanitkong 头像 kinglisky 头像 morimanong 头像 panpanpanya 头像 daoshanghundesijidou 头像 bukenengdeshi 头像 wanzuqiudeshangba 头像
点赞 16 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.