raect-query μ μ© μ posts
posts νμ΄μ§λ 무ν μ€ν¬λ‘€λ‘ μΆκ°μ μΈ ν¬μ€νΈλ₯Ό λ μμ²ν΄μ€λ μν μ λ΄λΉνκ³ μμ΅λλ€.
- fetchMorePosts
offset μ΄ λ³ν λλ§λ€ 무ν μ€ν¬λ‘€μμ μΆκ°μ μΈ ν¬μ€νΈλ€μ λΆλ¬μ΅λλ€.
- fetchNewPosts
μ±λ μ νμ (μ±λ μμ΄λκ° λ³ν λλ§λ€) μλ‘μ΄ ν¬μ€νΈλ€μ λΆλ¬μ΅λλ€.
const fetchMorePosts = useCallback(async () => { if (offset > 0 && postsData.length >= 10) { const data = await getPosts(channelId, offset); const editedData = editPostData(data.data); setPostsData([...postsData, ...editedData]); } }, [offset]); const fetchNewChannel = useCallback(async () => { const data = await getPosts(channelId, 0); const reformedData = editPostData(data.data); setPostsData(reformedData); setOffset(0); }, [channelId]);
useEffect(() => { fetchNewChannel(); }, [channelId]); useEffect(() => { fetchMorePosts(); }, [offset]);
μ΄μ μ΄ λΉλκΈ° μ²λ¦¬λ€μ νμ±λκ»μ μλ €μ£Όμ react-query λ‘ λ°κΏλ³΄λ €κ³ ν©λλ€.
react-query μκ°
μ°μ react-query λ₯Ό μ¬μ©νκΈ° μν΄ νλ‘μ νΈ μ΅μλ¨ μ»΄ν¬λνΈμ λ€μκ³Ό κ°μ΄ QueryClientProvider λ₯Ό μ€μ ν΄μ€λλ€.
// App.tsx import { QueryClient, QueryClientProvier } from 'react-query'; const queryClient = new QueryClient(); return ( <QueryClientProvider client={queryClient} > <App /> </QueryClientProvider> )
posts λ₯Ό λ°μμ€λ κ²½μ° GET μμ²μ 보λ΄λ―λ‘ useQuery λ₯Ό μ¬μ©νκ² λ©λλ€.
useQuery λ λ€μκ³Ό κ°μ΄ μ¬μ©ν μ μμ΅λλ€.
useQuery(key, callback, options)
λ€μ λκ°μ§ λ°©λ²μΌλ‘ μ¬μ©ν μ μμ΅λλ€.
const { data, isLoading, ... } = useQuery(queryKey, queryFn, { }); const result = useQuery({ queryKey, queryFn, });
λ§€κ°λ³μ
- key
λ°μμ¬ λ°μ΄ν°λ₯Ό μλ³νλ λ¬Έμμ΄ νΉμ λ°°μ΄ κ°μ
λλ€.
λ°°μ΄μ κ²½μ° μ²«λ²μ§Έ μΈμλ‘λ λ°μ΄ν°λ₯Ό μλ³νλ λ¬Έμμ΄μ, λλ¨Έμ§ μΈμλ‘λ μ½λ°±ν¨μ λ΄λΆλ‘ μ λ¬ν λ§€κ°λ³μλ₯Ό λ°μμ¬ μ μμ΅λλ€.
- callback
λΉλκΈ° μ²λ¦¬ ν¨μκ° λ€μ΄κ°λλ€. μ¬κΈ° API νΈμΆμ λ£μΌλ©΄ λ©λλ€.
- options
API μμ²μ λ€μν μ΅μ
μ μ€μ ν μ μμ΅λλ€. ν΄λΉ μ΅μ
μ μ¬κΈ°μ μ¬μ©νμ§ μμΌλ―λ‘ μλ΅ν©λλ€!
λ°νκ°
λ€μκ³Ό κ°μ λ°νκ°μ κ°μ Έμ¬ μ μμ΅λλ€.
const { isLoading, isError, data, error } = useQuery( // ... )
- isLoading
μΊμ±λ λ°μ΄ν°κ° μλ κ²½μ° λ‘λ© μ¬λΆμ λ°λΌ
true
νΉμ false
μ κ°μ κ°μ§λλ€.μΊμ±λ λ°μ΄ν°κ° μλ κ²½μ°
false
μ κ°μ κ°μ§λλ€.- isError
μλ¬κ° λ°μν κ²½μ°
true
κ° λ©λλ€.- data
μμ²μ μ±κ³΅ν κ²½μ° λ°μμ¬ λ°μ΄ν°μ
λλ€.
- error
쿼리 ν¨μμ μ€λ₯κ° λ°μν κ²½μ° μ€λ₯ κ°μ²΄λ₯Ό λ°μ΅λλ€.
- refetch
μ¬κΈ°μ μΆκ°μ μΌλ‘
refetch
λ₯Ό λ°μμ¬ μ μλλ°, refetch λ μλμΌλ‘ ν΄λΉ 쿼리λ₯Ό λ€μ μμ²ν©λλ€.react-query μ μ©
μ λ°©λ² μ€ λλ²μ§Έ λ°©λ²μ μ¬μ©νμ¬ posts μ½λμ μ μ©νλ©΄ λ€μκ³Ό κ°μ΅λλ€.
- key κ°μ
getChannelPosts
λ‘ μ€μ ν΄μ£Όμλ€. κ·Έλ¦¬κ³ channelId μ offset μ ν¨μ λ§€κ°λ³μλ‘ λ겨μ€λλ€.
- μ½λ°±ν¨μλ‘ μ¬μ©ν λΉλκΈ° ν¨μλ₯Ό λ€μκ³Ό κ°μ΄ μ§μ ν©λλ€.
const { data } = useQuery({ queryKey: ['getChannelPosts', channelId, offset], queryFn: async () => { await getPosts(channelId, offset) }, })
channelId μ offset μ μΈμλ‘ μ λ¬ν΄μ£ΌμμΌλ―λ‘ λ κ°μ΄ λ°λ λλ§λ€ μλμΌλ‘ refetch κ° μ€νλ©λλ€.
λ°λΌμ κΈ°μ‘΄μ κΈ΄ μ½λλ₯Ό λ€μκ³Ό κ°μ΄ μμ ν΄μ€ μ μμ΅λλ€.
μμ μ
const fetchMorePosts = useCallback(async () => { if (offset > 0 && postsData.length >= 10) { const data = await getPosts(channelId, offset); const editedData = editPostData(data.data); setPostsData([...postsData, ...editedData]); } }, [offset]); const fetchNewChannel = useCallback(async () => { const data = await getPosts(channelId, 0); const reformedData = editPostData(data.data); setPostsData(reformedData); setOffset(0); }, [channelId]); useEffect(() => { fetchNewChannel(); }, [channelId]); useEffect(() => { fetchMorePosts(); }, [offset]);
μμ ν
const { data: postsData } = useQuery({ queryKey: ['getChannelPosts', channelId, offset], queryFn: async () => { const data = await getPosts(channelId, offset); const editedData = editPostData(data); return offset === 0 ? editedData : [...data, ...editedData]; } });
μΆκ° λ¬Έμ
ν¬μ€νΈ 10κ° λ―Έλ§μΌ μ μ€νμ μ μ© μ νκΈ°
- λ§μ§λ§ μμ μμλ₯Ό κ΄μ°°νλ©΄ observer κ° offset μ μ¦κ°μν΅λλ€. μ¬κΈ°μ λ λΆλ¬μ¬ ν¬μ€νΈκ° μμμλ, μ¦ ν¬μ€νΈκ° 10κ° λ―Έλ§μΈ κ²½μ°μλ λ§μ§λ§ μμκ° κ°μμ±μ΄ true κ° λλ©° offset μ΄ μ¦κ°νκ² λ©λλ€.
κ·Έλ¦¬κ³ offset μ΄ λ³νκ² λ¨μΌλ‘μ¨ μΆκ°μ μΈ ν¬μ€νΈλ₯Ό λΆλ¬μ€κ² λ©λλ€. λ μμ±λ ν¬μ€νΈκ° μμΌλ postsData κ° undefined κ° λμ΄ λΉνλ©΄μ΄ μΆλ ₯λ©λλ€.
κ·Έλμ μλμ κ°μ΄ childNode κ° 10 μ΄μμΈ κ²½μ°μλ§ κ°μμ±μ κ΄μ°°νλλ‘ μμ νμμ΅λλ€.
useEffect(() => { if ( postsRef.current && postsRef.current.childNodes.length >= 10 ) { const { lastChild } = postsRef.current; lastChild && observe(lastChild); } }, [postsData]);
- 무ν μ€ν¬λ‘€μ΄ μλ¬κ° λλ λ¬Έμ κ° μ겨μ console μ μΆλ ₯ν΄λ³΄λ react-query λ‘ λ°μμ€λ λ°μ΄ν°λ₯Ό postsData μ λ£μ΄λκ³ , μλ‘μ΄ λ°μ΄ν°λ₯Ό μΆκ°μ μΌλ‘ λ£μ΄μ£Όλ €κ³ νλλ° μ΄μ λ°μ΄ν°κ° undefined κ° λλ©΄μ spread μ°μ°μκ° μ μ©λμ§ μλ λ¬Έμ κ° μκ²Όλ€.
κ²°κ΅ postsData λ₯Ό state λ‘ λ°λ‘ λΆλ¦¬νκ³ , react-query λ‘ λ°μμ€λ λ°μ΄ν°κ° μ
λ°μ΄νΈ λ λλ§λ€ postsData λ₯Ό λ³κ²½νλ λ‘μ§μΌλ‘ λ³κ²½νλ€.
const [postsData, usePostsData] = useState<EditedPost[]>([]); const { data } = useQuery({ queryKey: ['getChannelPosts', channelId, offset], queryFn: async () => { const data = await getPosts(channelId, offset); const editedData = editPostData(data); return editedData; } }); useEffect(() => { if (data) { setPostsData(offset === 0 ? data : [...postsData, ...data]); } }, []);