一、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;
三、目录结构