一个极简的React状态管理库。
- 仅100+ LOC,代码简单到你可以现场读完
- 充分使用组合概念,将状态管理方法以函数式的方式进行组织
import {
type SimpleAction,
useSimpleReducer,
buildSimpleReducerContext,
} from "./path/to/source";
interface AppState {
firstName: string;
lastName: string;
secret: string;
}
type Action = SimpleAction<AppState>;
// 任何reducer只是一个高阶函数...
function ActionChangeFirstName(first: string): Action {
return async ({ mutate }) => {
// 使用mutate修改状态并触发一次界面更新
mutate({ firstName: first });
};
}
function ActionChangeLastName(last: string): Action {
return async ({ mutate }) => {
mutate({ lastName: last });
};
}
// 你可以自由组合reducer来执行一个更复杂的事务...
function ActionChangeFullName(first: string, last: string): Action {
return async ({ dispatch }) => {
// 使用dispatch执行其他reducer
await dispatch(ActionChangeFirstName(first));
// 天然支持异步操作
const lastFromRemote = await FetchLastNameFromRemote();
await dispatch(ActionChangeLastName(lastFromRemote ?? last));
};
}
function ActionChangeFullNameInBatch(first: string, last: string): Action {
return async ({ dispatch, batch }) => {
// 不想多次更新界面?使用batch进行更新合并
batch(async () => {
await dispatch(ActionChangeFirstName(first));
await dispatch(ActionChangeLastName(last));
// 包含batch的reducer之间还可以嵌套
await dispatch(ActionChangeSomethingInBatch());
});
};
}
const {
SimpleReducerContext: AppStateContext,
useSimpleReducerContext: useAppStateReducer,
} = buildSimpleReducerContext<AppState>();
function App() {
// 初始化
const reducer = useSimpleReducer<AppState>(() => ({
firstName: "John",
lastName: "Doe",
secret: "MyPrecious",
}));
// 取值
const firstName = reducer.state.firstName;
const onInputFirstName = useCallback((content: string) => {
// 需要保持引用稳定,不想引入额外dependency?使用pick
const secret = reducer.pick("secret");
// 修改
reducer.dispatch(ActionChangeFullName(content, secret));
}, []);
return (
<AppStateContext provider={reducer}>
<Content />
</AppStateContext>
);
}
function Content() {
// 在Context范围内的子组件中使用reducer
const { state, dispatch } = useAppStateReducer();
}