为什么绑定 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 属性 作为参数,以及用户名和密码。

我写在一个单独的答案上,以便更好地与第一个区别开来