Recently I have started using React Native 0.61.5
and React navigation 5.x
. Now I need to pass a parent function into a child screen. For example, I want to change navbar icon by pressing button in tab of TabNavigator nested in StackNavigator. Previously (navigation ver. 3.x) I was using getActiveChildNavigationOptions
for my needs but now it's removed. So the only way to achieve this goal is to pass custom functions to child components.
Here in example code I want to change from XXXXXXXX
to YYYYYYYYY
:
const TabA = ({ route }) => (
<View>
<Text>Tab A</Text>
<Button
title="Change header"
onPress={() => route.params.setHeaderRightName("YYYYYYYYY")}/>
</View>
)
const TabB = () => <><Text>Tab B</Text></>
const Tabs = createBottomTabNavigator();
const TabsNavigator = ({ navigation }) => {
const [headerRightName, setHeaderRightName] = useState("XXXXXXXX");
useLayoutEffect(() => navigation.setOptions({
headerRight: () => <MyNavIcon name={headerRightName}/>
}), [headerRightName]);
return (
<Tabs.Navigator>
<Tabs.Screen name="tab-a" component={TabA} initialParams={{ setHeaderRightName }} />
<Tabs.Screen name="tab-b" component={TabB} />
</Tabs.Navigator>
);
}
const Stack = createStackNavigator();
export default App = () => (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="tabs" component={TabsNavigator} />
<Stack.Screen name="another-screen" component={AnotherScreen} />
</Stack.Navigator>
</NavigationContainer>
)
Everything is working fine, but I am getting this warning:
Full text:
Non-serializable values were found in the navigation state, which can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state for more details.
So how can I pass function from parent to child if warning says I cannot pass function using route params?
class MainScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
title: null
};
this.updateTitle = this.updateTitle.bind(this);
}
updateTitle(title) {
this.setState({title: title});
}
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="NewScreen"
options={{
headerShown: true,
headerTitle: this.state.title
}}>
{(props) => <NewScreen {...props} updateTitle={this.updateTitle}/>}
</Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
);
}
}
The documentation page the link in the warning is pointing to says:
If you don't use state persistence or deep link to the screen which accepts functions in params, then you can ignore the warning. To ignore it, you can use YellowBox.ignoreWarnings.
So, in my case, I can ignore this warning and pass functions thought route params safely.
YellowBox.ignoreWarnings([
'Non-serializable values were found in the navigation state',
]);
or for react native 0.63 and higher:
LogBox.ignoreLogs([
'Non-serializable values were found in the navigation state',
]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With