UNPKG

react-create-store

Version:

State management just using basic React hooks api within 80 lines of code 在80行代码内仅使用基本的 React hooks API 进行状态管理

79 lines (78 loc) 3.21 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { createContext, useContext, useMemo, } from "react"; import { useImmerReducer } from "use-immer"; export { useImmer, useImmerReducer } from "use-immer"; /** * Batch declaring providers in JSX * * [idx] where to start, default is 0 * * [providers] the order of the providers parameter array is exactly the order of the context hierarchy * * 在 JSX 中批量声明上下文 * * [providers] 参数数组的顺序,正好是上下文层级的顺序 * * [idx] 从哪个位置开始迭代声明,默认是 0 * * @export * @param {PropsWithChildren<{ * idx?: number * providers: FC<PropsWithChildren>[] * }>} { * children, * idx = 0, * providers, * } * @return {*} */ export function BatchProviders({ children, idx = 0, providers, }) { const Provider = providers[idx]; return Provider ? (_jsx(Provider, { children: _jsx(BatchProviders, { idx: idx + 1, providers: providers, children: children }) })) : (children); } /** * Create a store,reducer with immer inside * * 创建一个 store, 内部有 immer 的 reducer * * @export * @template S * @template A * @template Async * @param {S} intialState * [initialState] The initial state of the reducer in the store (cannot be null or undefined) * [initialState] reducer 的初始状态(不能为 null 或 undefined) * @param {(state: Draft<S>, action: Partial<A>) => void} reducer * [reducer] The reducer function of the store,State is immutable(by immer) * [reducer] store 的 reducer 函数,State 是不可变的(通过 immer) * @param {(state: S, dispatch: Dispatch<Partial<A>>) => Async} [useHook=() => * ({} as unknown as Async)] * [useHook] A custom hook that returns an object where each property is an asynchronous function({} by default) * [useHook] 一个自定义 hook,返回一个对象,对象的每个属性都是一个异步函数(默认是 {}) * @return {*} */ export default function createStore(intialState, reducer, useHook = () => ({})) { const StateContext = createContext(intialState); const DispatchContext = createContext(() => { }); const AsyncContext = createContext({}); return { useReducer() { const state = useContext(StateContext); const dispatch = useContext(DispatchContext); const async = useContext(AsyncContext); // 因为 dispatch 和 async 都是稳定不变的,因此返回 state 时,可以顺带一起返回 return [state, dispatch, async]; }, useDispatch() { return useContext(DispatchContext); }, useAsync() { return useContext(AsyncContext); }, Provider(props) { const [state, dispatch] = useImmerReducer(reducer, undefined, () => props.initialState === undefined ? intialState : props.initialState); const async = useHook(state, dispatch); return (_jsx(StateContext.Provider, { value: state, children: _jsx(DispatchContext.Provider, { value: dispatch, children: _jsx(AsyncContext.Provider, { value: useMemo(() => async, []), children: props.children }) }) })); }, }; }