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>)