为什么绑定 prop 不起作用,但使用箭头函数却起作用?
Why doesn't binding a prop work but using an arrow function does?
我想创建一个登录页面,当字段为空时显示错误消息。我使用函数组件、状态和道具来保持 UI 与逻辑分离。所以我有一个 UserSignInController
其中 returns 一个 UserSignInView
显示在屏幕上。
当我为登录按钮设置 onPress
回调时,它会在控制器中调用 onClickCheckLogin()
。但是设置错误消息只有在我使用箭头函数作为道具时才有效,如果我使用 .bind(this)
它不会。
这个有效
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');
}
};
这不起作用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');
}
};
有了这个我得到一个错误TypeError: _this.setErrorMessage is not a function. (In '_this.setErrorMessage('Username/password empty')', '_this.setErrorMessage' is undefined)
我认为问题在于 renderSignInView
本身被定义为箭头函数。 this
关键字没有指向组件,因此调用 setErrorMessage
会导致错误。尝试更改为以下内容:
function renderSignInView(){
//Component
}
我找到了答案here。您无法从外部访问函数的局部属性。与 console.log
一起显示的 globalObject
只是 window 对象。所以,用 .bind()
绑定是行不通的。作为替代方案,您可以传递 setErrorMessage
属性 作为参数,以及用户名和密码。
我写在一个单独的答案上,以便更好地与第一个区别开来
我想创建一个登录页面,当字段为空时显示错误消息。我使用函数组件、状态和道具来保持 UI 与逻辑分离。所以我有一个 UserSignInController
其中 returns 一个 UserSignInView
显示在屏幕上。
当我为登录按钮设置 onPress
回调时,它会在控制器中调用 onClickCheckLogin()
。但是设置错误消息只有在我使用箭头函数作为道具时才有效,如果我使用 .bind(this)
它不会。
这个有效
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');
}
};
这不起作用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');
}
};
有了这个我得到一个错误TypeError: _this.setErrorMessage is not a function. (In '_this.setErrorMessage('Username/password empty')', '_this.setErrorMessage' is undefined)
我认为问题在于 renderSignInView
本身被定义为箭头函数。 this
关键字没有指向组件,因此调用 setErrorMessage
会导致错误。尝试更改为以下内容:
function renderSignInView(){
//Component
}
我找到了答案here。您无法从外部访问函数的局部属性。与 console.log
一起显示的 globalObject
只是 window 对象。所以,用 .bind()
绑定是行不通的。作为替代方案,您可以传递 setErrorMessage
属性 作为参数,以及用户名和密码。
我写在一个单独的答案上,以便更好地与第一个区别开来