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