Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Você usa APIs do jeito errado
Search
Hugo
July 16, 2022
Programming
86
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Você usa APIs do jeito errado
Uma introdução ao React Query v3
Hugo
July 16, 2022
More Decks by Hugo
See All by Hugo
ReferenceError: talk is not defined
hugooliveirad
1
60
Três hábitos para escrever CSS escalável
hugooliveirad
0
690
Three habits to write scalable CSS
hugooliveirad
0
73
Mantendo webapps em produção, sem dor de cabeça
hugooliveirad
1
290
Minha webapp está em produção, e agora?
hugooliveirad
0
53
Other Decks in Programming
See All in Programming
yield再入門 #phpcon
o0h
PRO
0
1.1k
5分で問診!Composer セキュリティ健康診断
codmoninc
0
1k
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
180
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
470
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
150
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
140
Foundation Models frameworkで画像分析
ryodeveloper
1
610
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
12
18k
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
690
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
680
これって Effect でできたのでは? / TSKaigi Mashup Kansai #2
susisu
0
240
Featured
See All Featured
Discover your Explorer Soul
emna__ayadi
2
1.3k
The Pragmatic Product Professional
lauravandoore
37
7.4k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
210
Believing is Seeing
oripsolob
1
190
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
790
WENDY [Excerpt]
tessaabrams
11
39k
How to Think Like a Performance Engineer
csswizardry
28
2.7k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
540
Transcript
Você usa APIs do jeito errado Uma introdução ao React
Query
Oi, eu sou o Hugo E eu também já usei
APIs do jeito errado
Vamos começar um projeto novo
None
None
A API da timeline está pronta
A API da timeline está pronta Beleza, a gente vai
implementar
É só substituir os valores do JSON pela API const
[timelineData, setTimelineData] = useState(); useEffect(() => { async function fetchData() { const response = await fetch('/timeline'); const data = await response.json(); setTimelineData(data); } fetchData(); }, [])
É só substituir os valores do JSON pela API const
[timelineData, setTimelineData] = useState(); useEffect(() => { async function fetchData() { const response = await fetch('/timeline'); const data = await response.json(); setTimelineData(data); } fetchData(); }, [])
É só substituir os valores do JSON pela API const
[timelineData, setTimelineData] = useState(); useEffect(() => { async function fetchData() { const response = await fetch('/timeline'); const data = await response.json(); setTimelineData(data); } fetchData(); }, [])
É só substituir os valores do JSON pela API const
[timelineData, setTimelineData] = useState(); useEffect(() => { async function fetchData() { const response = await fetch('/timeline'); const data = await response.json(); setTimelineData(data); } fetchData(); }, [])
É só substituir os valores do JSON pela API const
[timelineData, setTimelineData] = useState(); useEffect(() => { async function fetchData() { const response = await fetch('/timeline'); const data = await response.json(); setTimelineData(data); } fetchData(); }, [])
function useTimelineData() { } É só substituir os valores do
JSON pela API const [timelineData, setTimelineData] = useState(); useEffect(() => { async function fetchData() { const response = await fetch('/timeline'); const data = await response.json(); setTimelineData(data); } fetchData(); }, [])
function TimelinePage() { const timelineData = useTimelineData(); if (!timelineData) {
return null; } return ( <Timeline> {timelineData.posts.map((post) => ( <Post key={post.id} post={post} /> ))} </Timeline> ) }
Tá pronto, chefe
Tá pronto, chefe Agora a API dos posts está pronta
Tá pronto, chefe Agora a API dos posts está pronta
Beleza, vamos lá. Tá fácil.
None
function usePostData(id) { const [postData, setPostData] = useState(); useEffect(() =>
{ async function fetchData() { const response = await fetch(`/posts/${id}`); const data = await response.json(); setPostData(data); } fetchData(); }, [id]) return postData; }
function usePostData(id) { const [postData, setPostData] = useState(); useEffect(() =>
{ async function fetchData() { const response = await fetch(`/posts/${id}`); const data = await response.json(); setPostData(data); } fetchData(); }, [id]) return postData; }
Tá pronto
Tá pronto Tá pronto?
Tá pronto Tá pronto? Alguém consegue me dizer quais são
os problemas da implementação atual?
Alguém consegue me dizer quais são os problemas da implementação
atual?
Erros e Exceções
Erros e Exceções
Error Erros e Exceções
Batching
1 4 3 2 useTimelineData Batching
1 4 3 2 useTimelineData Batching Batching
1 4 3 2 useTimelineData Batching Batching
Caching
Caching
Caching useTimelineData
Cache Invalidation New
Cache Invalidation New New
Race Condition
Race Condition Busca T T T T T T
Busca T Ty Type TypeSc TypeScri TypeScript T T T
T T T Race Condition
Busca T Ty Type TypeSc TypeScri TypeScript Requisições T Ty
Type TypeSc TypeScri TypeScript T T T T T T Race Condition
T Ty Type TypeSc TypeScri TypeScript Requisições T Ty Type
TypeSc TypeScri TypeScript Race Condition Latência T Ty Type TypeSc TypeScri TypeScript
Retries
Retries
1 4 3 2 Requisições Retries
1 4 3 2 Requisições 1 4 3 2 Retries
1 4 3 2 Requisições 1 4 3 2 3
Retry Retry Retry Sucesso Retries Retries
Erros e Exceções Batching Caching Cache Invalidation Race Condition Retries
Erros e Exceções Batching Caching Cache Invalidation Race Condition Retries
Cancelamento Prefetching In fi nite Pagination Polling Optimistic Updates Refetching E muito mais
Ninguém implementa tudo isso
Você não quer ter que implementar tudo isso
React Query
function usePostData(id) { const [postData, setPostData] = useState(); useEffect(() =>
{ async function fetchData() { const response = await fetch(`/posts/${id}`); const data = await response.json(); setPostData(data); } fetchData(); }, [id]) return postData; }
async function fetchData() { const response = await fetch(`/posts/${id}`); const
data = await response.json(); setPostData(data); }
async function fetchData() { const response = await fetch(`/posts/${id}`); const
data = await response.json(); setPostData(data); }
async function fetchData() { const response = await fetch(`/posts/${id}`); return
response.json(); setPostData(data); }
function usePostData(id) { return useQuery(['posts', id], () => fetchPost(id)); }
function usePostData(id) { return useQuery(['posts', id], () => fetchPost(id)); }
function usePostData(id) { return useQuery(['posts', id], () => fetchPost(id)); }
function usePostData(id) { return useQuery(['posts', id], () => fetchPost(id)); }
function PostPage({params: {id}}) { const {data, isLoading} = usePostData(id); if
(isLoading) { return null; } return ( <Post post={data.post} /> ) }
function PostPage({params: {id}}) { const {data, isLoading} = usePostData(id); if
(isLoading) { return null; } return ( <Post post={data.post} /> ) }
function PostPage({params: {id}}) { const {data, isLoading} = usePostData(id); if
(isLoading) { return null; } return ( <Post post={data.post} /> ) }
const { data, isLoading, isSuccess, error, isError, refetch, /* ...
*/ } = usePostData(id);
Erros e Exceções Batching Caching Cache Invalidation Race Condition Retries
Cancelamento Prefetching In fi nite Pagination Polling Optimistic Updates Refetching Sites Robustos
Con fi gurável
staleTime: 0
staleTime: 0 ... 0 ms
cacheTime: 1000 * 60 * 5
retry: 3
refetchOnWindowFocus: true
refetchOnWindowFocus: true ... ...
function usePostData(id) { return useQuery(['posts', id], () => fetchPost(id), {
staleTime: 1000 * 20, cacheTime: 1000, refetchOnWindowsFocus: false, }); }
Mutations
New
New New u
New New useMutation
async function createPost(post) { const response = await fetch('/posts', {
method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify(post) }); return response.json(); }
function CreatePostPage() { const mutation = useMutation(createPost); const handleSubmit =
useCallback((event) => { event.preventDefault(); const data = new FormData(event.target); const post = Object.fromEntries(data.entries()); mutation.mutate(post); }, [mutation]); return mutation.isLoading ? (<Spinner />) : ( <form onSubmit={handleSubmit}> {/* ... */} </form> ) }
function CreatePostPage() { const mutation = useMutation(createPost); const handleSubmit =
useCallback((event) => { event.preventDefault(); const data = new FormData(event.target); const post = Object.fromEntries(data.entries()); mutation.mutate(post); }, [mutation]); return mutation.isLoading ? (<Spinner />) : ( <form onSubmit={handleSubmit}> {/* ... */} </form> ) }
function CreatePostPage() { const mutation = useMutation(createPost); const handleSubmit =
useCallback((event) => { event.preventDefault(); const data = new FormData(event.target); const post = Object.fromEntries(data.entries()); mutation.mutate(post); }, [mutation]); return mutation.isLoading ? (<Spinner />) : ( <form onSubmit={handleSubmit}> {/* ... */} </form> ) }
function CreatePostPage() { const mutation = useMutation(createPost); const queryClient =
useQueryClient(); const handleSubmit = useCallback((event) => { event.preventDefault(); const data = new FormData(event.target); const post = Object.fromEntries(data.entries()); mutation.mutate(post, { onSuccess: () => { queryClient.invalidateQueries('timeline'); } }); }, [mutation]); return mutation.isLoading ? (<Spinner />) : ( <form onSubmit={handleSubmit}> {/* ... */} </form> )
queryClient.invalidateQueries(['posts', id]);
DevTools
DevTools
Hugo, eu parei de prestar atenção Já uso o getServerProps
Não preciso do React Query
Hugo, eu parei de prestar atenção Já uso o getServerProps
Não preciso do React Query E se eu te falar que...
E se eu te falar que... React Query trabalha com
dados assíncronos
E se eu te falar que... React Query trabalha com
dados assíncronos Qualquer dado assíncrono
const [stream, setStream] = useState(); useEffect(() => { async function
getMedia() { const newStream = await navigator.mediaDevices.getUserMedia({video: true}); setStream(newStream); } getMedia(); }, [])
function useUserMedia() { return useQuery( ['userMedia'], () => navigator.mediaDevices.getUserMedia({video: true})
); }
function useUserMedia() { return useQuery( ['userMedia'], () => navigator.mediaDevices.getUserMedia({video: true}),
{ staleTime: Infinity } ); }
"The best part is no part"
None
De nada!
None
None
None