JotaiJotai

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

useAtomEffect

useAtomEffect 使用 atomEffect 根据 atoms 或 props 的变化运行副作用。

当它依赖的 atoms 发生变化或 effectFn 本身发生变化时,effectFn 会重新运行。如果 effectFn 是在组件中定义的函数,请确保对其进行记忆化。

⚠️ 注意:总是优先使用 稳定版本的 useMemo 和 useCallback 来避免额外的 atomEffect 重新计算。你可以依赖 useMemo 作为性能优化,但不能作为语义保证。在未来,React 可能会选择“忘记”一些之前记忆化的值,并在下次渲染时重新计算它们,例如,为屏幕外的组件释放内存。

import { useMemoOne as useStableMemo } from 'use-memo-one'
import { useAtomValue } from 'jotai/react'
import { atomEffect } from 'jotai-effect'
type EffectFn = Parameters<typeof atomEffect>[0]
export function useAtomEffect(effectFn: EffectFn) {
useAtomValue(useStableMemo(() => atomEffect(effectFn), [effectFn]))
}

示例用法

import { useCallbackOne as useStableCallback } from 'use-memo-one'
import { atom, useAtom } from 'jotai'
import { atomFamily } from 'jotai/utils'
import { useAtomEffect } from './useAtomEffect'
const channelSubscriptionAtomFamily = atomFamily<Channel>(
(channelId: string) => {
return atom(new Channel(channelId))
},
)
const messagesAtom = atom<Message[]>([])
function Messages({ channelId }: { channelId: string }) {
const [messages] = useAtom(messagesAtom)
useAtomEffect(
useStableCallback(
(get, set) => {
const channel = get(channelSubscriptionAtomFamily(channelId))
const unsubscribe = channel.subscribe((message) => {
set(messagesAtom, (prev) => [...prev, message])
})
return unsubscribe
},
[id],
),
)
return (
<>
<h1>You have {messages.length} messages</h1>
<hr />
{messages.map((message) => (
<div key={message.id}>{message.text}</div>
))}
</>
)
}