👉 unstated-next 基于 React 心智模型(hook+context)而设计的状态管理。 👈
在 react hook 出现以前,有基于单一数据源,使用纯函数修改状态的 redux & react-redux 也有基于 Object.defineProperty 和 Proxy 来进行数据拦截访问的 mobx ,但伴随着 react 16.8 的出现,咱们能够基于自带的 hook 去实现状态管理也就是 unstated-nextjavascript
... import { createContainer } from "unstated-next"; function useCounter(initialState = 0) { let [count, setCount] = useState(initialState); let decrement = () => setCount(count - 1); let increment = () => setCount(count + 1); return { count, decrement, increment }; } //使用 createContainer 将 useCounter改形成提供状态和方法的组件 let Counter = createContainer(useCounter); function CounterDisplay() { //从被处理过的 useCounter 中拿到状态和方法 let counter = Counter.useContainer(); return ( <div> <button onClick={counter.decrement}>-</button> <span>{counter.count}</span> <button onClick={counter.increment}>+</button> </div> ); } function App() { return ( <Counter.Provider> <CounterDisplay /> {/* 经过initialState属性注入初始值 */} <Counter.Provider initialState={2}> <CounterDisplay /> </Counter.Provider> </Counter.Provider> ); } render(<App />, document.getElementById("root"));
unstated-next 作了什么?前端
Provider 注入
和 组件获取获取 Store
这两个方法import { createContext, createElement, useContext } from "react"; export default useHook => { const Context = createContext(); const Provider = ({ init, children }) => { return createElement(Context.Provider, { value: useHook(init) }, children); }; const useContainer = () => useContext(Context); return { Provider, useContainer }; };
Provider
和useContainer
的对象value
,子节点不变,返回:<xxx.Provider value={方法,状态...}>{children}</xxx.Provider>
useContainer
拿到 当前 Context.Provider 中的 value 状态和方法 并返回在 unstated-next 中每个被处理为 数据对象 的组件若是想要被共享,须要在最外层逐级包裹java
<Container1.Provider> <Container2.Provider> <Container3.Provider>MyApp</Container3.Provider> </Container2.Provider> </Container1.Provider>
咱们能够经过 相似 compose 函数进行处理,将全部 数据对象 组件经过 reduce 逐级叠加返回一个相似洋葱的 Provider,调用的时候只须要使用Provider
包裹住业务组件react
export const composeProvider = (...commonFun) => ({ children }) => { return commonFun.reduceRight((child, { init, Provider }) => { return <Provider init={init}>{child}</Provider>; }, children); }; //进行调用 const Provider = reduceProvider({ ...xxxState1, init: 100 }, xxxState2); export default () => ( <Provider> <ExamplePage1 /> <ExamplePage2 /> <ExamplePage3 /> </Provider> );
查看完整代码git
大功告成!github
总结redux
其实 unstated-next 实现很简单,通俗来说就是一个闭包,使用于简单的业务场景,且写法过于灵活,一旦遇到 class 组件的状况,就又要回到旧的写法,因此只能说有利有弊微信
至此,谢谢各位在百忙之中点开这篇文章,但愿对大家能有所帮助,相信你对 unstated-next 有了大概的认实,若有问题欢迎各位大佬指正。闭包
欢迎添加个人微信共同讨论前端技术问题(备注:qian)ide
求个 star,谢谢你们了