该计划摈弃了 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 等轻量且使用方便等内部状态治理库。