Tutorial React Native: Mengenal React Query
Pengambilan data dari sumber jarak jauh diperlukan di hampir setiap program yang akan Anda buat. Sayangnya, mengambil data tidak semudah mengambil dan menyajikannya. Pertimbangkan hal berikut:
Apa yang harus kita lakukan sambil menunggu data dimuat?
Bagaimana jika terjadi kesalahan?
Bagaimana cara menjaga data saya tetap terkini?
Bagaimana jika koneksi internet pengguna saya lemah atau lambat?
React Query dapat membantu Anda dengan semua tugas ini.
Hari ini, kami akan menampilkan aplikasi etalase sederhana dari API pengambilan ke React Query.
1. App.js
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { QueryClient, QueryClientProvider } from 'react-query';
import { MoviesListScreen } from './screens/MoviesListScreen';
import { MovieDetailsScreen } from './screens/MovieDetailsScreen';
const Stack = createStackNavigator();
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: 2 } },
});
function MoviesStack() {
return (
<Stack.Navigator initialRouteName="MoviesList">
<Stack.Screen
name="MoviesList"
component={MoviesListScreen}
options={{
headerTitle: 'Movies',
}}
/>
<Stack.Screen
name="MovieDetails"
component={MovieDetailsScreen}
options={{
headerTitle: 'Movie details',
}}
/>
</Stack.Navigator>
);
}
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<NavigationContainer>
<MoviesStack />
</NavigationContainer>
</QueryClientProvider>
);
}
2. MoviesListScreen.js
import * as React from 'react';
import { FlatList, RefreshControl } from 'react-native';
import { useQuery } from 'react-query';
import { LoadingIndicator } from '../components/LoadingIndicator';
import { ErrorMessage } from '../components/ErrorMessage';
import { Divider } from '../components/Divider';
import { ListItem } from '../components/ListItem';
import { useRefreshByUser } from '../hooks/useRefreshByUser';
import { useRefreshOnFocus } from '../hooks/useRefreshOnFocus';
import { fetchMovies } from '../lib/api';
export function MoviesListScreen({ navigation }) {
const { isLoading, error, data, refetch } = useQuery(['movies'], fetchMovies);
const { isRefetchingByUser, refetchByUser } = useRefreshByUser(refetch);
useRefreshOnFocus(refetch);
const onListItemPress = React.useCallback(
(movie) => {
navigation.navigate('MovieDetails', {
movie,
});
},
[navigation]
);
const renderItem = React.useCallback(
({ item }) => {
return <ListItem item={item} onPress={onListItemPress} />;
},
[onListItemPress]
);
if (isLoading) return <LoadingIndicator />;
if (error) return <ErrorMessage message={error.message}></ErrorMessage>;
return (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={(item) => item.title}
ItemSeparatorComponent={() => <Divider />}
refreshControl={
<RefreshControl
refreshing={isRefetchingByUser}
onRefresh={refetchByUser}
/>
}></FlatList>
);
}
3. MovieDetailsScreen.js
import * as React from 'react';
import { View, RefreshControl, StyleSheet, ScrollView } from 'react-native';
import { Title, Paragraph } from 'react-native-paper';
import { useQuery } from 'react-query';
import { LoadingIndicator } from '../components/LoadingIndicator';
import { ErrorMessage } from '../components/ErrorMessage';
import { useRefreshByUser } from '../hooks/useRefreshByUser';
import { fetchMovie } from '../lib/api';
export function MovieDetailsScreen({ route }) {
const { isLoading, error, data, refetch } = useQuery(
['movie', route.params.movie.title],
() => fetchMovie(route.params.movie.title),
{ initialData: route.params.movie }
);
const { isRefetchingByUser, refetchByUser } = useRefreshByUser(refetch);
if (isLoading) return <LoadingIndicator />;
if (error) return <ErrorMessage message={error.message}></ErrorMessage>;
return (
<ScrollView
refreshControl={
<RefreshControl
refreshing={isRefetchingByUser}
onRefresh={refetchByUser}
/>
}>
<View style={styles.titleRow}>
<Title>
{data.title} ({data.year})
</Title>
</View>
{data.info ? (
<>
<View style={styles.infoRow}>
<Paragraph>{data.info.plot}</Paragraph>
</View>
<View style={styles.actorsRow}>
<Paragraph>
{data.info.actors.slice(0, -1).join(', ') +
' or ' +
data.info.actors.slice(-1)}
</Paragraph>
</View>
</>
) : (
<LoadingIndicator />
)}
</ScrollView>
);
}
const styles = StyleSheet.create({
titleRow: {
flexDirection: 'row',
margin: 20,
},
infoRow: {
flexDirection: 'row',
margin: 20,
},
actorsRow: {
flexDirection: 'column',
margin: 20,
marginTop: 10,
},
});
Catatan: Kode yang ditampilkan di atas hanya bagian utama, silakan periksa kode contoh pada snack untuk kode lebih detail
Snack Link : https://snack.expo.dev/@rudiahmad/react-query-simple-example