Navigation parameter is undefined - react-native

I am trying to pass a parameter by navigation screen. But when I receive the parameter at child screen it gives me undefined.
Parent Screen :
navigate('Screen2', {itemId: 'sales'})
Screen2
const { navigation } = this.props;
const id = navigation.getParam('itemId');
console.log(id);
Result :
Undefined

You can try this code
const { id } = this.props.navigation.state.params;
console.log(id);
OR
const id = this.props.navigation.state.params.id;
console.log(id);

Hope this works!
Parent Screen
this.props.navigation.push('Screen2', {itemId: 'sales'});
Screen2
const { id } = this.props.navigation.state.params;
console.log(id);
//Hope you're using react-navigation

It looks like, the way you are using getParams method is incorrect. Try following:
const id = this.props.navigation.getParam('itemId', 'defaultId');
Or else you can also use solutions by #Jothi Basu & #hong develop.

Use navigate.state.params
Screen2:
const id = this.props.navigation.state.params.itemId

Related

React Native check if the route is not null

I am getting route from react-native in one component as below:
const { route } = this.props;
const { fromPage } = route.params;
But sometimes the route is null 9perhaps it was not set when navigating), how to check if that is null before getting the value like above?
Should look at useNavigationState:
useNavigationState is a hook which gives access to the navigation state of the navigator which contains the screen. It's useful in rare cases where you want to render something based on the navigation state.
documentation
Probably you can use a conditional statement, as I have shown below.
const { route } = this.props;
if (route && route.params) {
const { fromPage } = route.params;
// use `fromPage` here
} else {
// handle the case where `route` or `route.params` is null
}
You can write like this:
const { fromPage } = this.route?.params || {}
fromPage param has type as string | undefined, you can check the condition of the param before using it

params is cached and shows older values on return to the same screen

I use react-navigation 5 and having issues because the params shows older values.
ScreenList.js
const handleFirstUser = () => {
const userDetail = {'name': 'First User'};
navigation.navigate('Details', { detail: userDetail});
}
const handleSecondUser = () => {
const userDetail = {'name': 'Second User'};
navigation.navigate('Details', { detail: userDetail});
}
The methods are called from a button and do go to Details Screen but the value is whichever was loaded initially:
ScreenDetails.js
const DetailsScreen = (props) =>{
const { navigation, route } = props;
const { params } = route;
const userDetail = params.name;
}
First time the app the loads, first user is loaded and correctly shows name. Then go back to the list screen, click user two. Still the first user is shown. I tried to clean up with useEffect but it doesnt have any effect:
useEffect(()=>{
return(()=>{
navigation.setParams({name: undefined});
});
}, [])
how can I reset setParams each it laods and use the values passed to it currently?

React Native hooks - correct use of useEffect()?

I'm new to hooks and ran across this setup on SO and wanted to confirm that this is the correct pattern. I was getting the RN "unmounted component" leak warning message before and this seemed to solve it. I'm trying to mimic in some way compnentDidMount. This is part of a phone number verify sign up flow and onMount I want to just check for navigation and then fire off a side effect, set mounted true and then unmount correctly.
const SMSVerifyEnterPinScreen = ({ route, navigation }) => {
const [didMount, setDidMount] = useState(false)
const { phoneNumber } = route.params
useEffect(() => {
if(navigation) {
signInWithPhoneNumber(phoneNumber)
setDidMount(true)
}
return () => setDidMount(false)
}, [])
if (!didMount) { return null }
async function signInWithPhoneNumber(phoneNumber) {
const confirmation = await auth().signInWithPhoneNumber('+1'+phoneNumber)
...
}
return (
...
)
}
RN 0.62.2 with react-nav 5 - thanks!
Since signInWithPhoneNumber is a async function and will setState you will see warning it the component is unmounted before the response is available
In order to handle such scenarios you can keep a variable to keep track whether its mounted or not and then only set state is the mounted variable is true
However you do not need to return null if component has unmounted since that doesn't accomplish anything. The component is removed from view and will anyways not render anything.
Also you do not need to maintain this value in state, instead use a ref
const SMSVerifyEnterPinScreen = ({ route, navigation }) => {
const isMounted = useRef(true)
const { phoneNumber } = route.params
useEffect(() => {
if(navigation) {
signInWithPhoneNumber(phoneNumber)
}
return () => {isMounted.current = false;}
}, [])
async function signInWithPhoneNumber(phoneNumber) {
const confirmation = await auth().signInWithPhoneNumber('+1'+phoneNumber)
...
}
return (
...
)
}

Getting the current routeName in react navigation

I want to get the name of the current routeName in react navigator. I came across three solutions:
1. const { routeName } = navigation.state.routes[navigation.state.index];
2. this.props.navigation.state.RouteName
3. const route = navigationState.routes[navigationState.index];
The first one seems to work fine. For the second one, I am not sure how to use it. The third option (as given in official documentation), generates the error with
ReferenceError: navigationState is undefined.
Please help me out in which is the correct way to find the name of the active screen while navigation.
function getActiveRouteName(navigationState) {
if (!navigationState) {
return null
}
const route = navigationState.routes[navigationState.index]
if (route.routes) {
return getActiveRouteName(route)
}
return route.routeName
}
// Example Usage
const currentScreen = getActiveRouteName(this.props.router);
if (currentScreen === 'Login') {
// do something
}

Get passing variable by name error

I am new to react native, and I can successfully run navigate example (https://reactnavigation.org/docs/en/params.html) locally:
But I don't understand, why this code:
const { navigation } = this.props;
const itemId = navigation.getParam('name', 'NO-ID');
can succefully get the value of variable 'name', but if I modified it to:
//const { navigation } = this.props;
const itemId = this.props.getParam('name', 'NO-ID');
Android emulator would complain:
undefined is not a function (evaluating const itemId = this.props.getParam('name', 'NO-ID') )
?
Since { navigation } would be same as this.props ?
you have confused with es6 destructuring.
const { navigation } = this.props;
is equal to
const navigation = this.props.navigation;
It is just a syntactic sugar.
In your case you should correct your code like below:
const itemId = this.props.navigation.getParam('name', 'NO-ID')
You forgot this.props.NAVIGATION :)
// const { navigation } = this.props;
const itemId = this.props.navigation.getParam('name', 'NO-ID');