Reputation: 1052
I understand that navigation and route props are automatically passed to the target screen when you navigate. So you can access navigation when you're in that screen, say screen B.
What I want to do is in Screen A, where the navigator is defined, I'd like to be able to setParams every so often. How can I refer to the navigator in this case?
For example, I would like to do this:
navigator.screen('posts').setParams({videoData: stuff});
A.js
const A = () => {
const Tab = createMaterialTopTabNavigator();
const navigator = <Tab.Navigator>
<Tab.Screen name="posts" component={FeedList} />
</Tab.Navigator>;
useEffect(()=> {
fetchStuff((stuff)=> {
navigator.screen('posts').setParams({videoData: dataState});
});
},[]);
return <>{navigator}</>;
}
Inside the useEffect, I ideally would be able to dynamically set the route params of the target screen.
I tried using initialParams and a state, but the initialParams doesn't seem to update in the target screen when the state changes. (So, I would accept that as an answer too, if you know why that's not working.)
not working initialParams example:
const A = () => {
const [dataState, setDataState] = useState(null);
const Tab = createMaterialTopTabNavigator();
useEffect(()=> {
fetchStuff((stuff)=> {
setDataState(stuff); // this doesn't seem to update initialParams
});
},[]);
return <Tab.Navigator>
<Tab.Screen name="posts" component={FeedList} initialParams={{videoData: dataState}} />
</Tab.Navigator>;
}
Upvotes: 1
Views: 1359
Reputation: 144
You can use setParams function.
Here is the code of updating of the state of a nested tab's screen after 3 seconds.
import React, {useContext, useState, createContext, useEffect} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createStackNavigator} from '@react-navigation/stack';
import {CommonActions} from '@react-navigation/native';
const Stack = createStackNavigator();
const KeyContext = createContext();
const DELAY_TIME = 3000;
const KeyContextProvider = (props) => {
const [routeKey, setRouteKey] = useState(null);
return (
<KeyContext.Provider
value={{key: routeKey, setKey: (value) => setRouteKey(value)}}>
{props.children}
</KeyContext.Provider>
);
};
const AScreen = ({navigation}) => {
const Tab = createBottomTabNavigator();
const {key} = useContext(KeyContext);
React.useEffect(() => {
if (key) {
setTimeout(() => {
navigation.dispatch({
...CommonActions.setParams({value: 'Updated state'}),
source: key,
});
}, DELAY_TIME);
}
}, [navigation, key]);
return (
<Tab.Navigator>
<Tab.Screen
name="screen B"
component={BScreen}
initialParams={{value: 'Initial state'}}
/>
<Tab.Screen name="screen C" component={CScreen} />
</Tab.Navigator>
);
};
const BScreen = ({route}) => {
const val = route.params?.value || null;
const {setKey} = useContext(KeyContext);
useEffect(() => {
setKey(route.key);
}, [route, setKey]);
return (
<View style={styles.screen}>
<Text>Screen B</Text>
<Text>{val}</Text>
</View>
);
};
const CScreen = () => {
return (
<View style={styles.screen}>
<Text>Screen C</Text>
</View>
);
};
export default function App() {
return (
<KeyContextProvider>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Screen A" component={AScreen} />
</Stack.Navigator>
</NavigationContainer>
</KeyContextProvider>
);
}
const styles = StyleSheet.create({
screen: {flex: 1, justifyContent: 'center', alignItems: 'center'},
});
Upvotes: 1