動態

詳情 返回 返回

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.