XState
Jotai的状态管理既原始又灵活,但有时候也意味着过于自由。XState是一个复杂的库,为状态管理提供了更好、更安全的抽象。
安装
要使用此功能,你必须安装 xstate
和 jotai-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') && (<inputautoFocusdefaultValue={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的课程。
(注意:在课程中,它使用的是 jotai/xstate
,已被 jotai-xstate
取代。)