Introduction
To fetch data in React Native, you can use both the native fetch API and third-party libraries like TanStack Query (formerly React Query). Below is an overview of both methods, including examples for both approaches within a React Native app created with Expo.
Using Fetch API in React Native
React Native supports the fetch API for making HTTP requests, which works similarly to the browser-based fetch method. You can use it to fetch data from remote APIs. Here's how you can use it:
import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet } from 'react-native'; const App = () => { const [data, setData] = useState([]); const [loading, setLoading] = useState(true); const url = 'https://jsonplaceholder.typicode.com/posts'; // API endpoint useEffect(() => { fetch(url) .then((response) => response.json()) .then((json) => { setData(json); setLoading(false); }) .catch((error) => console.error('Error fetching data: ', error)); }, []); return ( {loading ? ( Loading... ) : ( data.map((post) => ( {post.title} {post.body} )) )} ); }; export default App;
In this example:
- The fetch method is used to request data from the jsonplaceholder API.
- The useEffect hook ensures that the request runs once when the component is mounted.
- The response is parsed using response.json() and stored in the state, which is then rendered in a list.
To handle loading states and errors more gracefully:
useEffect(() => { fetch(url) .then((response) => response.json()) .then((json) => { setData(json); }) .catch((error) => { console.error('Error fetching data: ', error); setError(true); }) .finally(() => { setLoading(false); }); }, []);
Using TanStack Query
TanStack Query offers a more powerful and flexible way to fetch and cache data in React Native. It automates many aspects of data fetching, including caching, background fetching, and pagination, and can simplify your API requests.To use TanStack Query in your Expo app, first, you need to install it:
npm install @tanstack/react-query
Then, wrap your app in the QueryClientProvider to set up the TanStack Query client:
import React from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import App from './App'; // Your app component const queryClient = new QueryClient(); export default function Main() { return ( <QueryClientProvider client={queryClient}> <App /> </QueryClientProvider> ); }
import React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import { useQuery } from '@tanstack/react-query'; const fetchPosts = async () => { const response = await fetch('https://jsonplaceholder.typicode.com/posts'); return response.json(); }; const App = () => { const { data, error, isLoading } = useQuery(['posts'], fetchPosts); if (isLoading) { return Loading...; } if (error) { return Error loading posts; } return ( {data.map((post) => ( {post.title} {post.body} ))} ); }; export default App;
In this example:
- The useQuery hook is used to fetch data.
- The query key ['posts'] uniquely identifies the request.
- The isLoading, error, and data states provide feedback to the user about the request status.
TanStack Query caches the fetched data, so if you make the same request multiple times, it will return the cached data (until the cache expires). You can configure this behavior to suit your needs, for example:
const { data, error, isLoading } = useQuery( ['posts'], fetchPosts, { staleTime: 5000, // Data is considered fresh for 5 seconds cacheTime: 10000, // Cache lasts for 10 seconds } );
If you want to make a POST request using TanStack Query, here's how you can do it:
import React from 'react'; import { Button, View, Text } from 'react-native'; import { useMutation } from '@tanstack/react-query'; const createPost = async (newPost) => { const response = await fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(newPost), }); return response.json(); }; const App = () => { const mutation = useMutation(createPost, { onSuccess: (data) => { console.log('Post created:', data); }, onError: (error) => { console.error('Error creating post:', error); }, }); const handleCreatePost = () => { const newPost = { title: 'New Post', body: 'This is a new post' }; mutation.mutate(newPost); }; return ( {mutation.isLoading && Creating post...} {mutation.isError && Error creating post!} {mutation.isSuccess && Post created successfully!} ); }; export default App;
Conclusion
In React Native, you can fetch data using the built-in fetch API, or you can use third-party libraries like TanStack Query for more advanced functionality. The native fetch API is suitable for basic API requests, while TanStack Query simplifies handling complex data-fetching scenarios with built-in caching, background updates, and error handling.For better performance and more control over your app’s state, TanStack Query is an excellent choice, especially when dealing with complex applications or frequently changing data.