该方案抛弃了Reducers + Action Types,主要分为三步:
- 基于 hooks 构建 Store
- 将 Store 基于 context 传递给子组件
- 子组件更新 Store,并触发渲染
1.基于 hooks 构建 Store
userStore.tsx
import { useState } from 'react'
export default function useUserStore () {
const [user, setUser] = useState<IUser>({ })
return {
setUser,
user,
}
}
loginStore.tsx
import { useState } from 'react'
export default function useLoginStore () {
const [login, setLogin] = useState(false)
return {
login,
setLogin,
}
}
2.将 Store 基于 context 传递给子组件
context.tsx
import useUserStore from "./userStore";
import useLoginStore from "./loginStore";
import { createContext } from "react";
export const context = createContext(null);
export default function Context({ children }) {
const userStore = useUserStore();
const loginStore = useLoginStore();
console.log("userStore", userStore);
const contextValue = {
userStore,
loginStore
};
return <context.Provider value={contextValue}>{children}</context.Provider>;
}
app.tsx
import Context from "./context";
import Child from "./child";
export default function Index() {
return (
<Context>
<Child />
</Context>
);
}
3.子组件更新 Store,并触发渲染, 完成。
child.tsx
import { useContext, useEffect } from "react";
import { context } from "./context";
export default function Child() {
const store = useContext(context);
console.log(store);
const { user, setUser } = store?.userStore || {};
const { login, setLogin } = store?.loginStore || {};
useEffect(() => {
setTimeout(() => {
setUser({ name: "AwesomeDevin" });
setLogin(true);
}, 2000);
}, [setUser, setLogin]);
return (
<div>
<p>{user?.name || "未命名"}</p>
<p>{login ? "已登陆" : "未登录"}</p>
</div>
);
}
在线DEMO https://codesandbox.io/s/reac...
简单场景下可以直接使用 useContext ,复杂应用下推荐使用 useContextSelector 库,更好地解决 context 存在的性能问题,当然也可以尝试 zustand / mobx 等轻量且使用方便等外部状态管理库。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。