JotaiJotai

상태
React를 위한 기본적이고 유연한 상태 관리

useAtomEffect

useAtomEffectatomEffect를 사용하여 아톰이나 props의 변화에 반응하는 사이드 이펙트를 실행합니다.

effectFn은 의존하는 아톰이 변경되거나 effectFn 자체가 변경될 때마다 다시 실행됩니다. effectFn이 컴포넌트 내부에서 정의된 함수라면 반드시 메모이제이션해야 합니다.

⚠️ 주의: 추가적인 atomEffect 재계산을 피하기 위해 항상 안정적인 버전의 useMemo와 useCallback을 사용하는 것을 권장합니다. 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
},
[channelId],
),
)
return (
<>
<h1>{messages.length}개의 메시지가 있습니다</h1>
<hr />
{messages.map((message) => (
<div key={message.id}>{message.text}</div>
))}
</>
)
}