Skip to content

Instantly share code, notes, and snippets.

@cherniavskii
Created March 29, 2020 17:34
Show Gist options
  • Save cherniavskii/ef283e8c1745e8c53333b70e23de3674 to your computer and use it in GitHub Desktop.
Save cherniavskii/ef283e8c1745e8c53333b70e23de3674 to your computer and use it in GitHub Desktop.
React Query + React Navigation
import React, { useEffect } from 'react';
import {
StyleSheet,
View,
Text,
AppState,
Button,
} from 'react-native';
import { Colors } from 'react-native/Libraries/NewAppScreen';
import 'react-native-gesture-handler';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { useFocusEffect } from '@react-navigation/native';
import { useQuery as useReactQuery, setFocusHandler } from 'react-query';
// refetch all queries on app focus
setFocusHandler((handleFocus) => {
function handler(state) {
if (state === 'active') {
handleFocus()
}
}
AppState.addEventListener('change', handler);
return () => {
AppState.removeEventListener('change', handler);
}
})
function Query({ query }) {
return (
<View style={styles.body}>
<View style={styles.sectionContainer}>
<Text style={styles.sectionTitle}>{query.status}</Text>
<Text style={styles.sectionDescription}>
Data: {query.data}
</Text>
<Text style={styles.sectionDescription}>
failureCount: {query.failureCount}
</Text>
<Text style={styles.sectionDescription}>
isFetching: {`${query.isFetching}`}
</Text>
</View>
</View>
)
}
function useQuery(...args) {
const query = useReactQuery(...args);
const isMountedRef = React.useRef(false);
useFocusEffect(React.useCallback(() => {
// do not refetch when query is initially mounted
if (isMountedRef.current) {
query.refetch()
}
}, [query.refetch]))
useEffect(() => {
isMountedRef.current = true;
}, [])
return query;
}
function Home({ navigation }) {
const query = useQuery('items-list', () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([
'first',
'second',
'third'
])
}, 1000);
});
},
)
return (
<>
<Query query={query} />
{(query.data || []).map(item => {
return (
<Button onPress={() => navigation.navigate('Details', { id: item })} title={item} key={item}></Button>
)
})}
</>
);
};
function Details({ route }) {
const id = route.params.id;
const query = useQuery(['item-details', id], () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${id} data`);
}, 1000);
});
},
)
return (
<>
<Query query={query} />
<Text>{route.params.id}</Text>
</>
);
};
const Stack = createStackNavigator();
function App() {
return (
<>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Details" component={Details} />
</Stack.Navigator>
</NavigationContainer>
</>
);
};
const styles = StyleSheet.create({
body: {
backgroundColor: Colors.white,
},
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: Colors.black,
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
color: Colors.dark,
},
});
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment