unstated-next的github地址
背景
使用react Hooks后,想共享组件逻辑,可以自定义Hook。
除了共享逻辑外,想共享状态,可以用useContext。
unstated-next可以做到即共享组件逻辑,又共享状态。而且它比较小(unstated-next 用 40 行代码号称 React 数据管理库的终结版。),源码仅用了react。
unstated-next这个库只做了一件事:
1.提供createContainer将自定义Hooks封装为一个数据对象,提供Provider注入和useContainer获取Store这两个方法。
API
1. createContainer(useHook)
import { createContainer } from "unstated-next"
function useCustomHook() {
let [value, setInput] = useState()
let onChange = e => setValue(e.currentTarget.value)
return { value, onChange }
}
let Container = createContainer(useCustomHook)
// Container === { Provider, useContainer }
2. <Container.Provider>
包含参数 initialState
function ParentComponent() {
return (
<Container.Provider initialState={2}>
<ChildComponent />
</Container.Provider>
)
}
3. Container.useContainer()
此API同 useContainer(Container)一样
// Container.useContainer()
function ChildComponent() {
let input = Container.useContainer()
return <input value={input.value} onChange={input.onChange} />
}
// useContainer(Container)
import { useContainer } from 'unstated-next';
function ChildComponent() {
let input = useContainer(Container);
return <input value={input.value} onChange={input.onChange} />
}
tips
- 可以在其他 hooks 内部组合 containers
- 保持containers小而集中
unstated-next无需优化。需要优化的都是标准的react优化。
示例
import React, { useState } from "react"
import { createContainer } from "unstated-next"
import { render } from "react-dom"
function useCounter(initialState = 0) {
let [count, setCount] = useState(initialState)
let decrement = () => setCount(count - 1)
let increment = () => setCount(count + 1)
return { count, decrement, increment }
}
let Counter = createContainer(useCounter)
function CounterDisplay() {
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 />
<Counter.Provider initialState={2}>
<div>
<div>
<CounterDisplay />
</div>
</div>
</Counter.Provider>
</Counter.Provider>
)
}
render(<App />, document.getElementById("root"))
unstated-next源码js版
import { createContext, useContext } from 'react';
export function createContainer(useHook) {
const Context = createContext();
const Provider = props => {
const value = useHook(props?.initialState);
return
<Context.Provider value={value}>{props.children}</Context.Provider>;
};
const useContainer = () => {
const value = useContext(Context);
return value;
};
return { Provider, useContainer };
}
export function useContainer(provider) {
return provider.useContainer();
}
其他react状态管理库:mobx、dva、redux-toolkit、Recoil、Jotai、Zustand、Valtio.