Get passing variable by name error - react-native

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');

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

How use Momentjs in React Native

Hi how can I use https://momentjs.com/docs/#/i18n/ in react native ? I exactly need to know how to change the language on my calendar.
Now I have name mounths in Polish but name days I have in english but I nedd Polish.
import momentPL from 'moment/src/locale/pl'
function TermeScreen({ route, navigation }) {
const { id, title } = route.params;
const [selectedDate, setSelectedDate] = useState(new Date());
moment.locale('pl',momentPL );
let startDate = moment()
Try this,
import moment from 'moment';
function TermeScreen({ route, navigation }) {
const { id, title } = route.params;
const [selectedDate, setSelectedDate] = useState(new Date());
let startDate = moment(selectedDate.format("YYYY-MM-DD");
}

Why doesn't binding a prop work but using an arrow function does?

I want to create a login page where an error message is displayed when fields are empty. I use function components, state and props to keep the UI separated from the logic. So I have a UserSignInController which returns a UserSignInView which gets displayed on screen.
When I set a onPress callback for the login button, it calls onClickCheckLogin() in the controller. But setting the error message only works if I use an arrow function as a prop, if I use .bind(this) it doesn't.
This works
UserSignInController.js:
import React, {useState} from 'react';
import { Linking, Alert } from 'react-native';
import UserSignInView from './UserSignInView';
import User from '../../User';
const renderSignInView = () =>
{
const [errorMessage, setErrorMessage] = useState('');
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
return (
<UserSignInView
errorMessage = {errorMessage}
setUsername = {setUsername}
setPassword = {setPassword}
//arrow function passing the state to onClickCheckLogin
checkLogin = {() => { onClickCheckLogin(username, password, setErrorMessage)}}
openPrivacyPolicy = {onClickOpenPrivacyPolicy}
/>
)
};
const onClickCheckLogin = (username, password, setMessageFunction) =>
{
if(!! username && !! password)
{
console.log("yeee");
}else
{
console.log('doooo');
setMessageFunction('Username/password empty');
}
};
This does not work UserSignInController.js:
import React, {useState} from 'react';
import { Linking, Alert } from 'react-native';
import UserSignInView from './UserSignInView';
import User from '../../User';
const renderSignInView = () =>
{
const [errorMessage, setErrorMessage] = useState('');
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
//bind function instead of arrow function
onClickCheckLoginCallback = onClickCheckLogin.bind(this);
return (
<UserSignInView
errorMessage = {errorMessage}
setUsername = {setUsername}
setPassword = {setPassword}
//use the binded version
checkLogin = {onClickCheckLoginCallback}
openPrivacyPolicy = {onClickOpenPrivacyPolicy}
/>
)
};
const onClickCheckLogin = () =>
{
if(!! this.username && !! this.password)
{
console.log("yeee");
}else
{
console.log('doooo');
this.setErrorMessage('Username/password empty');
}
};
With this I get an error TypeError: _this.setErrorMessage is not a function. (In '_this.setErrorMessage('Username/password empty')', '_this.setErrorMessage' is undefined)
I found the answer here. You can't access local properties of a function from the outside. That globalObject displayed with console.log is just the window object. So, binding with .bind() can't work. As an alternative, you may pass the setErrorMessage property as an argument, and also the username and password.
I wrote on a separate answer to better distinguish from the first one
I think that the problem is that renderSignInView is defined as an arrow function itself. The this keyword is not pointing to the component then, so calling setErrorMessage results in an error. Try changing to the following:
function renderSignInView(){
//Component
}

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 (
...
)
}

Navigation parameter is undefined

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