JotaiJotai

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

XState

Jotai的状态管理既原始又灵活,但有时候也意味着过于自由。XState是一个复杂的库,为状态管理提供了更好、更安全的抽象。

安装

要使用此功能,你必须安装 xstatejotai-xstate

npm i xstate jotai-xstate

atomWithMachine

atomWithMachine 使用XState机器创建一个新的原子。它接收一个函数 getMachine 来创建一个新的机器。getMachine 在第一次使用 get 参数时被调用,你可以用它来读取其他原子的值。

import { useAtom } from 'jotai'
import { atomWithMachine } from 'jotai-xstate'
import { assign, createMachine } from 'xstate'
const createEditableMachine = (value: string) =>
createMachine<{ value: string }>({
id: 'editable',
initial: 'reading',
context: {
value,
},
states: {
reading: {
on: {
dblclick: 'editing',
},
},
editing: {
on: {
cancel: 'reading',
commit: {
target: 'reading',
actions: assign({
value: (_, { value }) => value,
}),
},
},
},
},
})
const defaultTextAtom = atom('edit me')
const editableMachineAtom = atomWithMachine((get) =>
// `get` 只在初始化机器时可用
createEditableMachine(get(defaultTextAtom)),
)
const Toggle = () => {
const [state, send] = useAtom(editableMachineAtom)
return (
<div>
{state.matches('reading') && (
<strong onDoubleClick={send}>{state.context.value}</strong>
)}
{state.matches('editing') && (
<input
autoFocus
defaultValue={state.context.value}
onBlur={(e) => send({ type: 'commit', value: e.target.value })}
onKeyDown={(e) => {
if (e.key === 'Enter') {
send({ type: 'commit', value: e.target.value })
}
if (e.key === 'Escape') {
send('cancel')
}
}}
/>
)}
<br />
<br />
<div>
双击进行编辑。失去焦点或按 <code>enter</code> 提交。按 <code>esc</code> 取消。
</div>
</div>
)
}

在全局Provider中存储可重启的机器(无Provider模式)

当你的机器达到其最终状态时,它不能接收任何更多的事件。如果你的atomWithMachine在全局存储(也就是无Provider模式)中初始化,要重启它,你需要向你的机器发送一个 RESTART 事件,如下所示:

import { RESTART } from 'jotai-xstate'
const YourComponent = () => {
const [current, send] = useAtom(yourMachineAtom)
const isFinalState = current.matches('myFinalState')
useEffect(() => {
// 当组件卸载时,重启全局初始化的机器
return () => {
if (isFinalState) send(RESTART)
}
}, [isFinalState])
}

示例

查看带有atomWithMachine的示例:

可重启的机器:

教程

查看关于Jotai和XState的课程。

React中的复杂状态管理与Jotai和XState

(注意:在课程中,它使用的是 jotai/xstate,已被 jotai-xstate 取代。)