@luckyday/use-perf-context
v1.0.0
Published
a util to fix re-render for redux in hooks
Readme
高性能 Context
一.背景
解决了 Context re-render 问题,实现更精细化的控制策略。
常用策略有:多层Context方案 、 组件memo化方案。
使用起来代码量较多,因此使用发布订阅模式手撕高性能Context,使用起来也较为方便。
二.使用说明
// Context Store (./store.ts)
import { Payload2Action, Provider2Hook } from '@novel/dragon-utils/lib/use-perf-context';
export interface IUserInfo {
name: string;
age: number;
}
export interface IPayload {
SET_USER_INFO: Partial<IUserInfo>
}
// IAction = { type: 'SET_USER_INFO', payload: { name?: string; age?: number } }
export type IAction = Payload2Action<IPayload>;
export const initialState: IState = {
userInfo: {
name: "",
age: 0
},
};
export const globalReducer = (state: IState, action: IAction) => {
switch (action.type) {
case ActionType.SET_USER_INFO:
return {
...state,
userInfo: action.payload
};
default:
return state;
}
};
// usePerfContext<目标state集合的类型约束, dispatch的对象类型约束,目标属性名>(目标属性对象的属性名字符串)
// 使用类型推断和Provider2Hook工具泛型将hook与provider相关属性绑定
export const useUserContext = usePerfContext as Provider2Hook<IState, IAction>;
// Context Provider
import PerfContextProvider from '@novel/dragon-utils/lib/use-perf-context';
function App() {
return (
<PerfContextProvider state={initialState} reducer={globalReducer}>
<Header />
<YourComponents />
</PerfContextProvider>
);
}
// Context Consumer
import { useUserContext } from './store';
function Header() {
// same as: const [userInfo, dispatch] = usePerfContext<IState, IAction, 'userInfo'>('userInfo')
const [userInfo, dispatch] = useUserContext("userInfo");
const { name, age } = userInfo || {};
renderCount++;
const addAge = () => {
dispatch({
type: ActionType.SET_USER_INFO,
payload: { name: "阿吉", age: Number(age) + 1 }
});
};
return (
<div className={classPrefix}>
<div>{classPrefix}</div>
<div>用户名:{name}</div>
<div>年龄:{age}</div>
<button onClick={addAge}>年龄增长一岁</button>
<div>renderCount: {renderCount}</div>
</div>
);
}
三.example
在线demo: https://codesandbox.io/s/void4-context-rerender--proxy-completed-emv5n0?file=/src/store/index.tsx
