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