JotaiJotai

Jotai
React 原始而灵活的状态管理

Scope

这里有一些库可以扩展在React中使用Jotai的方式。

jotai-scope

虽然Jotai的Provider允许在子树下划定Jotai的存储范围,但我们不能在子树内使用树上方的存储。

一个解决方法是在useAtom和其他钩子中使用store选项。为了简化这种用例,jotai-scope提供了一个有范围的提供者和钩子。而不是指定store选项,有范围的提供者接受atoms属性,这些原子的使用在子树内有范围。

安装

npm i jotai-scope

计数器示例

import { atom, useAtom } from 'jotai'
import { ScopeProvider } from 'jotai-scope'
const countAtom = atom(0)
const anotherCountAtom = atom(0)
const Counter = () => {
const [count, setCount] = useAtom(countAtom)
const [anotherCount, setAnotherCount] = useAtom(anotherCountAtom)
return (
<>
<div>
<span>计数: {count}</span>
<button type="button" onClick={() => setCount((c) => c + 1)}>
增加
</button>
</div>
<div>
<span>另一个计数: {anotherCount}</span>
<button type="button" onClick={() => setAnotherCount((c) => c + 1)}>
增加
</button>
</div>
</>
)
}
const App = () => {
return (
<div>
<h1>第一个提供者</h1>
<ScopeProvider atoms={[anotherCountAtom]}>
<Counter />
</ScopeProvider>
<h1>第二个提供者</h1>
<ScopeProvider atoms={[anotherCountAtom]}>
<Counter />
</ScopeProvider>
</div>
)
}

createIsolation

Jotai的Provider和jotai-scope的有范围的提供者仍然使用全局上下文。

如果你正在开发一个依赖于Jotai的库,并且库用户可能在他们的应用中单独使用Jotai,他们可以共享相同的上下文。这可能会引起问题,因为他们指向意外的Jotai存储。

为了避免上下文冲突,jotai-scope导出了一个名为createIsolation的实用函数。

查看仓库中的示例:https://github.com/jotaijs/jotai-scope/tree/main/examples/01_isolation

bunshi(前身为jotai-molecules)

Jotai原子提供了一个基本的解决方案来优化重新渲染。全局定义的原子可以依赖于其他原子,但是它们不能依赖于组件树内的props和state。在组件树内定义原子是可能的,但是你需要以某种方式传递这些原子(例如,atoms-in-atom.)

bunshi是一个帮助这种用例的第三方库。

查看动机以获取更多详细信息。

安装

npm i bunshi

计数器示例

import { atom, useAtom } from 'jotai'
import { molecule, useMolecule, createScope, ScopeProvider } from 'bunshi/react'
const InitialCountScope = createScope(0)
const countMolecule = molecule((getMol, getScope) => {
const initialCont = getScope(InitialCountScope)
return atom(initialCont)
})
const Counter = () => {
const countAtom = useMolecule(countMolecule)
const [count, setCount] = useAtom(countAtom)
return (
<div>
{count} <button onClick={() => setCount((c) => c + 1)}>+1</button>
</div>
)
}
const App = () => (
<div>
<h1>初始值为1</h1>
<ScopeProvider scope={InitialCountScope} value={1}>
<Counter />
<Counter />
</ScopeProvider>
<h1>初始值为2</h1>
<ScopeProvider scope={InitialCountScope} value={2}>
<Counter />
<Counter />
</ScopeProvider>
<h1>默认</h1>
<Counter />
<Counter />
</div>
)