react中 多个层级 组件数据同用 组件之间传值 usecontext useReducer
封装同用的context
// useCountContext.tsx
// useCountContext.tsx
import React, { createContext, useContext, useReducer, Dispatch, ReactNode } from "react";// 状态类型
interface State {open: boolean;
}// Action 类型
/*** changeOpen 调整组件显示隐藏状态*/
type Action =| { type: "changeOpen";payload: boolean }| { type: "decrement" }| { type: "set"; payload: number };// 初始状态
const initialState: State = { open: true};// reducer 函数
function reducer(state: State, action: Action): State {switch (action.type) {case "changeOpen":return { ...state,open: action.payload };default:return state;}
}// 创建 Context
const CountStateContext = createContext<State | null>(null);
const CountDispatchContext = createContext<Dispatch<Action> | null>(null);// Provider 组件(局部用)
export const CountProvider = ({ children }: { children: ReactNode }) => {const [state, dispatch] = useReducer(reducer, initialState);return (<CountStateContext.Provider value={state}><CountDispatchContext.Provider value={dispatch}>{children}</CountDispatchContext.Provider></CountStateContext.Provider>);
};// 自定义 Hook
export const useCountState = () => {const context = useContext(CountStateContext);if (!context) throw new Error("useCountState 必须在 CountProvider 中使用");return context;
};export const useCountDispatch = () => {const context = useContext(CountDispatchContext);if (!context) throw new Error("useCountDispatch 必须在 CountProvider 中使用");return context;
};
使用目录机构
-- pages
---|----super/index.tsx
---|----super/view/index.tsx
---|----super/conmmont/modal.tsxsuper/index.tsx 使用这个context的顶层要引入import '@/App.css'
import { CountProvider } from '@/Context/SharedContext/Iindex'
import StocktakView from './viewData'//仓库管理
function Stocktaking(){return (<div><CountProvider><StocktakView></StocktakView></CountProvider></div>)
}export default Stocktaking----super/view/index.tsxconst { open } = useCountState();const dispatch = useCountDispatch();return (
<div onclick={()=>{dispatch({ type: "changeOpen",payload:false })
}}>
当前状态 {open ?“打开”:“关闭”}
</div>)其他组件一样的方式使用 即可