Showing data obtained by external sources is a core part of most frontend applications.
Most of the data comes from an API or a CMS. If the amount of data to be fetched is small, this can easily done with react-native hooks in combination with the fetch api. However, if the data flow between client and server grows more complicated, we are at risk of creating tons of unmaintainable spaghetti code.
To avoid this, we need a better tool for the job: React Query.
Here are the steps to get started with react query to improve your code:
1. Understand the difference between client state and server state
Client state lives in the browser, like form state, dark mode or whether a modal is opened or closed. Server state lives probably in some database and is served asynchronously.
Always use React Query for server state. Use native hooks like useState or useReducer for client state.
2. Install React-Query in your project
Follow the installation instructions and don't forget to set up the query client provider
3. In your code, replace data fetching code and states with the useQuery hook
Instead of writing this:
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch('https://rickandmortyapi.com/api/character');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const result = await response.json();
setData(result.results);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
}
fetchData();
}, []);
write this:
function fetchRickAndMortyCharacters() {
return fetch('https://rickandmortyapi.com/api/character')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => data.results);
}
const { data, isLoading, isError, error } = useQuery(['rickAndMortyCharacters'], fetchRickAndMortyCharacters);
The data you need to render will be in the destructured data
. Here is an example of how you can render the result:
if (isLoading) return <p>Loading...</p>;
if (isError) return <p>Error: {error.message}</p>;
if (!data) return <p>No data available</p>;
return (
<ul>
{data.map(character => (
<li key={character.id}>{character.name}</li>
))}
</ul>
);
4. Convert the useQuery hook into a custom hook
For better reusability, abstract this into a custom hook:
export function useRickAndMortyCharacters() {
return useQuery(['rickAndMortyCharacters'], fetchRickAndMortyCharacters);
}
now, from any component, you can just call the custom hook like so:
const { data, isLoading, isError, error } = useRickAndMortyCharacters();
That's it! If you want to go any further, read the docs and play around with different query options or with mutations.
Thanks for reading!
Top comments (2)
I'm just learning the basics of tanstack and found this article useful. Thanks so much!
This article is very helpful, thanks for sharing