I am fetching data from an API that has a JSON file, I am trying to pass the data from app to appstack to sessionsStack that will then bring the data to the home page, currently my console.logs are telling me that my data is only getting to the appStack.
App
import {AppStack} from '@miniclementine:navigation/AppStack';
import Colors from '@miniclementine:common/appearance/Colors';
const DATA = "https://cg0wsrc3ue.execute-api.us-east-1.amazonaws.com/dev/getSessions"
const App: () => React$Node = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
fetch(DATA)
.then((response) => response.json())
.then((json) => setData(json.sessions))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
console.log("the data: ", data)
}, []);
return (
<SafeAreaView style={styles.container}>
{ isLoading ? <ActivityIndicator /> : <AppStack data={data}/> }
</SafeAreaView>
);
};
App Stack
const Tab = createBottomTabNavigator();
export const AppStack = ({data}) => {
console.log("data in appstack", data)
return (
<NavigationContainer>
<Tab.Navigator tabBar={(props) => <MiniClementineTabBar {...props} />}>
<Tab.Screen name="Sessions" component={SessionsStack} data={data} />
<Tab.Screen name="Mantras" component={MantraStack} />
</Tab.Navigator>
</NavigationContainer>
);
};
Sessions Stack
import {createStackNavigator} from '@react-navigation/stack';
import SessionsHomepage from '@miniclementine:modules/sessions/SessionsHomepage';
import SessionsListPage from '@miniclementine:modules/sessions/SessionsListPage';
export const SESSIONS_HOMEPAGE = 'SESSIONS_HOMEPAGE';
export const SESSIONS_LIST_PAGE = 'SESSIONS_LIST_PAGE';
const Stack = createStackNavigator();
export default function SessionsStack({data}) {
console.log("data in SessionStack", data)
return (
<Stack.Navigator
screenOptions={{
headerShown: false,
}}>
<Stack.Screen name={'SESSIONS_HOMEPAGE'} component={SessionsHomepage} data={data} />
<Stack.Screen name={'SESSIONS_LIST_PAGE'} component={SessionsListPage} data={data} />
{/* @TODO: The two additional screens you need to create will be defined here */}
</Stack.Navigator>
);
}
Homepage
import {ClementineIcon, SectionHeader} from '@miniclementine:common/components';
import Colors from '@miniclementine:common/appearance/Colors';
import BlueButton from '@miniclementine:common/components/BlueButton';
import DiscoverMore from '@miniclementine:common/components/DiscoverMore';
export default function SessionHomepage({navigation, data, onPress}) {
console.log("data in HomePage", data)
const onPressSectionHeader = ({onPress}) => {
navigation.navigate('SESSIONS_LIST_PAGE', data)
};
const onPressSectionHeaderInvalid = () => {
alert('Out of scope for this task')
};
const Item = ({ item }) => (
<View style={styles.item}>
<TouchableOpacity style={styles.viewButton} onPress={() => {openSettingsModal(item) }}>
<Image source={item.image} style={styles.exerciseImage} />
<View style={styles.detailSection}>
<Text style={styles.title}>{item.title}</Text>
</View>
<ClementineIcon name="button-play" color={Colors.lilac} size={24} />
</TouchableOpacity>
</View>
);
const onContactPress = () => {
Linking.openURL('mailto:alina@clementineapp.co.uk?subject=SendMail&body=Description')
// Note: Not supported in iOS simulator, so you must test on a device.
// If you want to open an email client instead, I would suggest using the library react-native-email-link
}
return (
<SafeAreaView style={styles.container}>
<ScrollView>
<View style={styles.content}>
<SectionHeader
title="Morning Sessions"
onPress={onPressSectionHeaderInvalid}
textColor={Colors.Ink}
textColorSeeAll={Colors.cornflower}
/>
{/* <FlatList
data={DATA}
renderItem={({ item }) => <Item item={item} />}
keyExtractor={(item) => item.id}
/> */}
<DiscoverMore
title="Discover more sessions"
onPress={onPressSectionHeaderInvalid}
color={Colors.cornflower}
textColor={Colors.cornflower}
/>
<SectionHeader
title="Pick-me-ups"
onPress={onPressSectionHeader}
textColor={Colors.Ink}
textColorSeeAll={Colors.cornflower}
/>
<DiscoverMore
title="Discover more sessions"
onPress={onPressSectionHeader}
color={Colors.cornflower}
textColor={Colors.cornflower}
/>
</View>
<View style={styles.sleepSection}>
<Image
source={require('../../assets/illustrations/sleep_section.png')}
style={{height: 250, width: '100%'}}
/>
</View>
<View style={styles.sleepSection}>
<View style={styles.content}>
<View style={{paddingVertical: 10}}>
<SectionHeader
title="Sleep Sessions"
onPress={onPressSectionHeaderInvalid}
backgroundColor={Colors.ink}
textColor={Colors.stone}
textColorSeeAll={Colors.mint}
style={{paddingHorizontal: 10}}
/>
</View>
<Text>test</Text>
<DiscoverMore
title="Discover more sessions"
onPress={onPressSectionHeaderInvalid}
color={Colors.mint}
textColor={Colors.mint}
/>
</View>
</View>
<View style={{marginTop: '20%'}}></View>
<BlueButton title="Leave us feedback" onPress={onContactPress}/>
</ScrollView>
</SafeAreaView>
);
}
I am planning to put this data into a Flatlist inside the home page.
The best way to pass pros in navigation is to use params. And as your stack is loaded with data you can use the initialParams like below
<Tab.Screen name="Sessions" component={SessionsStack} initialParams={{data:data}}/>
You can access it in SessionsStack like below export default function SessionsStack({route}) { .....
<Stack.Screen name={'SESSIONS_HOMEPAGE'} component={SessionsHomepage} initialParams={{data:route.params.data}} />
You can do this in the screens which are nested as well.
Warning: this patterns is good only if the data is loaded only once, if you are thinking of changing the data use something like react context.