deno.land / x / jotai@v1.8.4 / tests / utils / useAtomCallback.test.tsx
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185import { StrictMode, useCallback, useEffect, useState } from 'react'import { fireEvent, render, waitFor } from '@testing-library/react'import { atom, useAtom } from 'jotai'import { useAtomCallback } from 'jotai/utils'import { StrictModeUnlessVersionedWrite, getTestProvider } from '../testUtils'
const Provider = getTestProvider()
it('useAtomCallback with get', async () => { const countAtom = atom(0)
const Counter = () => { const [count, setCount] = useAtom(countAtom) return ( <> <div>atom count: {count}</div> <button onClick={() => setCount((c) => c + 1)}>dispatch</button> </> ) }
const Monitor = () => { const [count, setCount] = useState(0) const readCount = useAtomCallback( useCallback((get) => { const currentCount = get(countAtom) setCount(currentCount) return currentCount }, []) ) useEffect(() => { const timer = setInterval(async () => { await readCount() }, 10) return () => { clearInterval(timer) } }, [readCount]) return ( <> <div>state count: {count}</div> </> ) }
const { findByText, getByText } = render( <StrictMode> <Provider> <Counter /> <Monitor /> </Provider> </StrictMode> )
await findByText('atom count: 0') fireEvent.click(getByText('dispatch')) await waitFor(() => { getByText('atom count: 1') getByText('state count: 1') })})
it('useAtomCallback with set and update', async () => { const countAtom = atom(0) const changeableAtom = atom(0) const Counter = () => { const [count, setCount] = useAtom(countAtom) return ( <> <div>count: {count}</div> <button onClick={() => setCount((c) => c + 1)}>dispatch</button> </> ) }
const Monitor = () => { const [changeableCount] = useAtom(changeableAtom) const changeCount = useAtomCallback( useCallback((get, set) => { const currentCount = get(countAtom) set(changeableAtom, currentCount) return currentCount }, []) ) useEffect(() => { const timer = setInterval(async () => { await changeCount() }, 10) return () => { clearInterval(timer) } }, [changeCount]) return ( <> <div>changeable count: {changeableCount}</div> </> ) }
const { findByText, getByText } = render( <StrictMode> <Provider> <Counter /> <Monitor /> </Provider> </StrictMode> )
await findByText('count: 0') fireEvent.click(getByText('dispatch')) await waitFor(() => { getByText('count: 1') getByText('changeable count: 1') })})
it('useAtomCallback with set and update and arg', async () => { const countAtom = atom(0)
const App = () => { const [count] = useAtom(countAtom) const setCount = useAtomCallback( useCallback((_get, set, arg: number) => { set(countAtom, arg) return arg }, []) )
return ( <div> <p>count: {count}</p> <button onClick={() => setCount(42)}>dispatch</button> </div> ) }
const { findByText, getByText } = render( <StrictMode> <Provider> <App /> </Provider> </StrictMode> )
await findByText('count: 0') fireEvent.click(getByText('dispatch')) await waitFor(() => { getByText('count: 42') })})
it('useAtomCallback with sync atom (#1100)', async () => { const countAtom = atom(0)
const Counter = () => { const [count, setCount] = useAtom(countAtom) const readCount = useAtomCallback(useCallback((get) => get(countAtom), [])) useEffect(() => { const promiseOrValue = readCount() if (typeof promiseOrValue !== 'number') { throw new Error('should return number') } }, [readCount]) return ( <> <div>atom count: {count}</div> <button onClick={() => setCount((c) => c + 1)}>dispatch</button> </> ) }
const { findByText, getByText } = render( <StrictModeUnlessVersionedWrite> <Provider> <Counter /> </Provider> </StrictModeUnlessVersionedWrite> )
await findByText('atom count: 0')
fireEvent.click(getByText('dispatch')) await findByText('atom count: 1')})
Version Info