React Native -Undefined param while coming back to previews screen - react-native

I have a root screen called selectlanguage once user select his language I'm passing that selected language as params to the Home screen, and then to "Home" children. but once I hit back button from that child screen to the Home that param turns to undefined that why when I want to open that child screen again it cause some issues.
Root screen selectedLanguage:
<View style={{ marginTop: 40 }}>
<Button
handleClick={() =>
navigation.navigate('Home', { lan: userLanData.value })
}
title={'NEXT'}
{...}
/>
Home screen:
const lan = route.params?.lan;
// and below i'm passing above param as props to Task screen
<Tasks
lanParam={lan}
{...}
/>
Task screen:
//Again passing it to another Child screen
<TouchableOpacity
onPress={() =>
navigation.navigate('byWords', {
id: item.id,
currentLevelName,
index,
lanParam, <-----
})
}>
{...}
</TouchableOpacity>
Task Child screen:
const lanParam = route?.params?.lanParam;
const colRef = collection(
db,
`${lanParam && lanParam}/${currLevelParam}/tasks/${id}/byWords/`
);
And from this point I had an idea to try send this Param back to home screen while coming back like this:
<Header
{...}
goBack={() =>
navigation.navigate('Home', { index, currLevelParam, lanParam })
}
/>
And now Home screen should look like this and I'm receiving that value back again:
Home screen:
const lan = route.params?.lan;
const lanParam = route.params?.lanParam;
// and below i'm passing above param as props to Task screen
<Tasks
lanParam={lan}
{...}
/>
But the problem is that, how could I use that value again since we have no access to the root screen again ?

it was easy to fix!!
I just modified lanParams to lan to keep same as Original param and update Home param again while coming back

Related

How to add screen at beginnig with CommonsActions.reset() in react navigation

I want to change screens order in navigation flow reseting navigation state
I want to change screens order in navigation flow, something like
{
condition ? <> <Screen A/> <Screen B/> </> : <> <Screen B/> <Screen A/> </>
}
following [https://reactnavigation.org/docs/auth-flow/#removing-shared-screens-when-auth-state-changes%5C]
How is the same screen this dont change the order (only when get condition from storage when app starts), so i was trying something like this to add screen A at beginnig keeping the others
navigation.dispatch((state) => {
const stateCopy = { ...state };
const routes = stateCopy?.routes?.unshift({ name: 'screen-A' });
// screen a dont have the key as the others in state
return CommonActions.reset({
...state,
routes,
index: 0,
});
});
Basically this doesnt works and i didnt find an example in [https://reactnavigation.org/docs/navigation-actions/#reset%5C] . How can i do this? Thanks.

React navigation doesn't refresh the page when parameter changed

I'm using react navigation to navigate between pages.
I have 2 pages. Let's call them A and B. I have some cards on page A and has touchable opacities on cards to navigate to page B with a different id (using this id for getting data from the server).
<TouchableOpacity style={styles.button} onPress={() => this.props.navigation.navigate('pageB',{id:this.props.id})} >
<Text>PageB</Text>
</TouchableOpacity>
It works well on first navigate. But when I navigate back to page A (by using side menu) and select another navigation button to navigate page B (different parameter) it navigates me to the same page with first navigate.
I have tried to use navigation key like that but I guess I could do that;
this.props.navigation.navigate('pageB',{id:this.props.id}, this.props.id)}
You have to set the new Parameter like this:
static navigationOptions = ({ navigation }) => {
let value = navigation.getParam("value");
return {
title: name,
headerRight: () => (<Button title="Edit" onPress={() => navigation.navigate("Edit", { val: value})} />),
};
And set somewhere always the new parameter like this:
let value = this.state.value;
this.props.navigation.setParams({value});

React - native StackNavigator refresh previous component after hitting back button

I'm stuck for weeks on this problem that I can't solve. I have been through a lot of different solution and none of them is working..
Let-s say I have component A and component B
Component A : contains a flatlist, when click on one item leads me to component B.
Component B: contains details of component A items, when clicking on a button update data, data that component A is using in state current, which make the clicked items turn to orange. I would like when hitting back button to update those data in component A and actually have the clicked items in orange, right now nothing is happening..
Component A :
async interventionList(){
const planningList = await getInterventionList(this.state.userToken, '2019-02-27', '2019-02-27');
this.setState({list: planningList});
}
renderItem = ({ item }) => (
<View>
<TouchableHighlight onPress={
() => this.props.navigation.navigate('InterventionStart', { getIntervention: () => this.interventionsList() })}>
<View style={[styles.block, this.state.current !== null && this.state.current.remoteInterventionId === item.num ? styles.began : styles.notbegan]}>
<Text> {SomeData} <Text>
</View>
</View>
</TouchableHighlight>
</View>
)
Component B :
componentWillUnmount() {
this.props.navigation.state.params.getIntervention();
}
But nothing happens. I tried to console log, to see if those functions where called after clickin on back button and they are... So I don't understand what I am doing wrong or is it not the way to do this at all ?
You can use willFocus method of react-navigation
in your componentDidMount or in your constructor
this.willFocus = this.props.navigation.addListener('willFocus', () => {
this.interventionList();
});
It will call your interventionList method whenever your component is about to be focused. Make sure you remove the listener on your componentWillUnmount
this.willFocus.remove();
For reference
https://reactnavigation.org/docs/en/navigation-events.html

Receiving wrong params when navigating to a route

I'm using react-navigation in my react native app.
In two different places I a have button to navigate to a route. One button also sends params and one button does not:
<Button onPress={() => { navigation.navigate('profile', { user: 'test' }) }} title="test" />
<Button onPress={() => { navigation.navigate('profile') }} title="test" />
In profile route I have a componentWillMount function to set state according to received params:
componentWillMount() {
const { params } = this.props.navigation.state;
if (params && params.hasOwnProperty('profile')) {
this.setState({
profile: params.profile
});
}
}
The problem is that if I press the first button (the one that sends params), then navigate back to the same view and press the second button, I'm still receiving the same params, even though the second button isn't sending any!
Not by my computer so I can't test.
But what if you navigate with the second button first? Do you still get the params passed to the page?
Also you dont mention what type navigation you sre navigating to. A stack, drawer or tab. Add some more info and I'll try to come back to you tomorrow.
But my impression is that you are navigating to the same page the second time and that page is already mounted. And hence not rerendered. Have you tried with componentDidUpdate an passing no variables on the second button?
This is the change I suggest in our discussion:
if (params && params.hasOwnProperty('profile')) {
this.setState({
profile: params.profile
});
else if (params && params.hasOwnProperty('profile')){
this.setState({
profile: null
});
}

React Native/Shoutem: navigateBack() not working

My Problem is that I would like to navigateBack() from the BountyDetailsScreen to the LoyaltyScreen, but the navigateBack() function call does not trigger any action. When I log the function it says:
The only thing I notice is, that the navigationStack is empty. When I do the same with the navigateTo function it is working, but then I have a messed up navigation stack.
In my LoyaltyScreen.js I am displaying a ListView. It is a RN ListView (not imported from shoutem).
LoyaltyScreen.js
renderRow(bounty) {
return (
<ListBountiesView
key={bounty.id}
bounty={bounty}
onDetailPress={this.openDetailsScreen}
redeemBounty={this.redeemBounty}
/>
);
}
ListBountiesView.js
The ListBountiesView renders each ListView Row and opens a Detail Screen when clicked on the Row.
render() {
const { bounty } = this.props;
return (
<TouchableOpacity onPress={this.onDetailPress}>
{bounty.type == 0 ? this.renderInShopBounty() : this.renderContestBounty()}
<Divider styleName="line" />
</TouchableOpacity>
);
}
BountyDetailsScreen.js
In the BountyDetailsScreen I display detailed information and would like to navigateBack() to the Loyalty Screen when I press a button.
<Button styleName="full-width" onPress={() => this.onRedeemClick()}>
<Icon name="add-to-cart" />
<Text>Einlösen</Text>
</Button>
onRedeemClick() {
const { bounty, onRedeemPress } = this.props;
onRedeemPress(bounty);
navigateBack();
}
navigateBack is an action creator. You need to map it to props and read it from props in your redeemClick function. Just executing the imported action creator won't do anything since it's not connected to Redux.
Here's an example of you map it to props:
export default connect(mapStateToProps, { navigateBack })(SomeScreen));
Here's how you use it:
const { navigateBack } = this.props;
navigateBack();
I can see that airmiha's answer is what you're looking for, but I just wanted to add onto it.
You can also use hasHistory to set up your #shoutem/ui NavigationBar (if you're using it) with a simple back button that utilises navigateBack().
<NavigationBar
styleName="no-border"
hasHistory
title="The Orange Tabbies"
share={{
link: 'http://the-orange-tabbies.org',
text: 'I was underwhelmed by The Orange Tabbies, but then I looked at that
sweet, sweet back button on the Nav Bar.
#MakeNavBarsGreatAgain',
title: 'Nevermind the cats, check the Nav Bar!',
}}
/>
You can find more examples with the NavigationBar component here.