React-hooks useReducer和useContext 封装和使用

一、React-hooks useReducer和useContext 封装和使用

  • userReducer.ts 数据存储文件
/**
* userReducer.ts
* 数据封装:reducer
*/ 
type Actions = 'updateUserId' | 'updateToken';
export interface TAction {
  type: Actions;
  data: any;
}
export interface TState{
    userId: string;
    token:string
}
    
//---------------- 

export const initialState: TState = {
    userId: '11111',
    token: '22222',
};

export const reducer: React.Reducer<TState, TAction> = (state, action) => {
    console.log("state===",state)
    switch (action.type) {
        case 'updateUserId':
            return {
                ...state,
                userId: action.data
            };
        case 'updateToken':
            return {
                ...state,
                token: action.data
            };
        default:
            return state;
    }
}
  • combineReducers.ts:reducre汇总
/**
*combineReducers.ts
*reducre汇总
*/
const combineReducers = function<T>(reducers:any){
  return function(state:any, action:any): T{
    let hasChanged:any;
    const nextState = Object.keys(reducers).reduce((result, key) => {
      result[key] = reducers[key](state[key], action);
      hasChanged = hasChanged || result[key] !== state[key];
      return result;
    }, {});
    return hasChanged ? nextState : state;
  };
}

export default combineReducers;
  • index.ts
/*
*index.ts
*入口文件:reducre入口文件
**/

import {
  initialState as userInitialState,
  reducer as userReducer,
  TState as TUserlState,
  TAction as TUserAction,
} from './userReducer';

import combineReducers from './combineReducers'

export const initialState = {
    userInfo: userInitialState
};

export type TState = {
    userInfo: TUserlState
};

export const reducer = combineReducers<TState>({
    userInfo: userReducer
});


export type TAction =  | TUserAction;

export interface TContextProps{
    state: TState;
    dispatch: React.Dispatch<TAction>;
}

二、用法

  • store/index.ts

    import React from 'react';
    
    import {
        TContextProps
    } from '@/reducer/index'
    
    const Store = React.createContext({} as TContextProps);
    
    export default Store;
    
    
  • Dome…ts

    // Dome 组件
    import React, { useContext, useEffect, useRef, useState, useReducer } from 'react';
    // 组件
    import Marquee from './components/Marquee';
    
    // 状态管理
    import { TState, TAction, reducer, initialState } from '@/reducer/index';
    import Store from './store/index';
    
    const TouchBattle = React.memo(() => {
      // 备用:store 仓库
      const [state, dispatch] = useReducer<React.Reducer<TState, TAction>>(reducer, initialState);
      const initState = true
    
      return (
        <Store.Provider value={{ state, dispatch }}>
          <div>
             {/* 调用组件 */}                   
            <Marquee></Marquee>
          </div>
        </Store.Provider>
      );
    });
    
    export default TouchBattle;
    
    
  • Marquee.ts 组件(使用reducer的数据)

    import React, { useContext, useEffect, useRef, useState, useReducer } from 'react';
    import Style from './index.module.scss';
    interface Props {
      marqueeWrap: object;
      marqueeContent?: object;
      children: React.ReactNode;
    }
    
    import Store from '../../store/index';
    
    // 文字走马灯滚动:keyframes
    const Marquee = React.memo<Props>((props) => {
      const { state, dispatch } = useContext(Store);
      const handleClick = ()=>{
        dispatch({type:'updateUserId',data:'1111111'})
      }
    
      return (
        <div >
          {/* 显示reducer */}
          <span>
            {state.userInfo.userId}
          </span>
          {/* 修改reducer */}
          <button onClick={handleClick}>
            点击修改
          </button>
        </div>
      );
    });
    
    export default Marquee;
    
    

三、目录结构
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值