context-state
React hooks 状态管理方案
安装
pnpm add context-state
介绍
React Context 和 useContext 存在一些性能问题,当 context 上下文改变时,所有使用到 context 的组件都会更新渲染。
使用 context-state
,开发者不必考虑 context 穿透问题 👏
Example
import { createContainer } from 'context-state'
import React from 'react'
function useCounter() {
const [count, setCount] = React.useState(0)
const increment = () => setCount((c) => c + 1)
return {
count,
increment,
}
}
const CounterContainer = createContainer(useCounter)
function CounterDisplay() {
const { count, increment } = CounterContainer.usePicker(['count', 'increment'])
return (
<div>
{count}
<button type='button' onClick={increment}>
ADD
</button>
</div>
)
}
function App() {
return (
<CounterContainer.Provider>
<CounterDisplay />
</CounterContainer.Provider>
)
}
render(<App />, document.getElementById('root'))
API
createContainer(useHook)
import { createContainer, useMemoizedFn } from 'context-state'
function useCustomHook() {
const [value, setInput] = useState()
const onChange = useMemoizedFn((e) => setValue(e.currentTarget.value))
return {
value,
onChange,
}
}
const Container = createContainer(useCustomHook)
<Container.Provider>
const Container = createContainer(useCustomHook)
function ParentComponent({ children }) {
return <Container.Provider>{children}</Container.Provider>
}
<Container.Provider value>
function useCustomHook(value = '') {
const [value, setValue] = useState(value)
}
const Container = createContainer(useCustomHook)
function ParentComponent({ children }) {
return (
<Container.Provider value='value'>
{children}
</Container.Provider>
)
}
Container.Consumer
function ChildComponent() {
return (
<Container.Consumer>
{(value) => <span>{value}</span>}
</Container.Consumer>
)
}
Container.useSelector()
监听当前容器中选择后的值,若值发生改变,则触发 rerender
function ChildComponent() {
const value = Container.useSelector((state) => state.value)
return <span>{value}</span>
}
Container.usePicker()
useSelector
的语法糖
function ChildComponent() {
const { value } = Container.usePicker(['value'])
return <span>{value}</span>
}
灵感来源
unstated-next | use-context-selector