首页 > 解决方案 > 未定义不是对象(评估'_this2.setState')

问题描述

我是 react-native 开发的新手,我尝试向我的应用程序添加登录名/注册,我通过电子邮件和 Facebook 登录工作正常(我在 Firebase 数据库中,所以没关系)。我想在用户登录后显示另一个视图。这是我的firebaseconfig(在我的登录名中导入):

    export async function loginUser(email, password) {
  try {
    firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then(response => {
        this.setState({ authentificated: true });
      });
  } catch (error) {
    console.log(error.toString);
  }
}

export async function facebookLogin() {
  Facebook.initializeAsync("928193664206969");
  const { type, token } = await Facebook.logInWithReadPermissionsAsync(
    "928193664206969",
    {
      permissions: ["public_profile"]
    }
  );

  if (type == "success") {
    const credential = firebase.auth.FacebookAuthProvider.credential(token);

    firebase
      .auth()
      .signInWithCredential(credential)
      .then(response => {
        this.setState({ authentificated: true });
      })
      .catch(error => {
        console.log(error);
      });
  }
}

这是我的登录页面:

import React from "react";
import { View, Text } from "react-native";
import EmailLoging from "../components/EmailLoging";
import { Welcome } from "../pages/Welcome";

export default class Login extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      email: "",
      password: "",
      authentificated: false
    };
  }

  renderCurrentState() {
    if (this.state.authentificated) {
      return <Welcome />;
    } else {
      return <EmailLoging />;
    }
  }

  render() {
    return this.renderCurrentState();
  }
}

在应用程序中,当我单击使用 facebook 登录时,它可以正常工作,然后我返回登录屏幕并显示以下错误:

undefined is not an object (evaluating '_this2.setState')
- node_modules\@firebase\auth\dist\auth.js:16:1054 in cb.prototype.toString
- node_modules\@firebase\auth\dist\auth.js:19:232 in <anonymous>
- node_modules\@firebase\auth\dist\auth.js:19:167 in xb
- node_modules\@firebase\auth\dist\auth.js:19:0 in wb
- node_modules\@firebase\auth\dist\auth.js:13:280 in <anonymous>
- node_modules\promise\setimmediate\core.js:37:14 in tryCallOne
- node_modules\promise\setimmediate\core.js:123:25 in setImmediate$argument_0
- node_modules\react-native\Libraries\Core\Timers\JSTimers.js:146:14 in _callTimer
- node_modules\react-native\Libraries\Core\Timers\JSTimers.js:194:17 in _callImmediatesPass
- node_modules\react-native\Libraries\Core\Timers\JSTimers.js:458:30 in callImmediates
* [native code]:null in callImmediates
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:407:6 in __callImmediates
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:143:6 in __guard$argument_0
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:384:10 in __guard
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:142:17 in __guard$argument_0
* [native code]:null in flushedQueue
* [native code]:null in invokeCallbackAndReturnFlushedQueue

我在 Stackoverflow 上进行了一些搜索,发现:TypeError: undefined is not an object (evalating 'this.setState')但我只有箭头函数,所以这不是问题..

谢谢

更新:现在我没有错误,但登录后屏幕没有改变,我的代码,登录功能:(firebaseConfig.js )

export async function loginUser(email, password) {
  try {
    firebase.auth().signInWithEmailAndPassword(email, password);
  } catch (error) {
    console.log(error.toString);
  }
}

export async function facebookLogin() {
  Facebook.initializeAsync("928193664206969");
  const { type, token } = await Facebook.logInWithReadPermissionsAsync(
    "928193664206969",
    {
      permissions: ["public_profile"]
    }
  );

  if (type == "success") {
    const credential = firebase.auth.FacebookAuthProvider.credential(token);

    firebase
      .auth()
      .signInWithCredential(credential)
      .catch(error => {
        console.log(error);
      });
  }
}

登录.js:

import React from "react";
import { View, Text } from "react-native";
import Welcome from "../pages/Welcome";
import Home from "../pages/Home";

export default class Login extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      email: "",
      password: "",
      authentificated: false
    };

    this.renderCurrentState = this.renderCurrentState.bind(this);
  }

  renderCurrentState = () => {
    if (this.state.authentificated) {
      return <Home />;
    } else {
      return <Welcome />;
    }
  };

  render() {
    return this.renderCurrentState();
  }
}

Welcome.js :

import React from "react";
import { StyleSheet, Text, Image } from "react-native";
import { LinearGradient } from "expo-linear-gradient";

import logo from "../../assets/icon.png";
import { Button, Icon, Container } from "native-base";
import { Actions } from "react-native-router-flux";
import { facebookLogin } from "../components/firebaseConfig";

export default class Welcome extends React.Component {
  render() {
    return (
      <LinearGradient
        colors={["#004aaf", "#000"]}
        style={{ flex: 1, alignItems: "center", justifyContent: "center" }}
      >
        <Container style={styles.backgroundImage}>
          <Image source={logo} style={styles.logo}></Image>
          <Text style={styles.loginText}>
            ─── Se connecter / S'inscrire avec ───
          </Text>
          <Button
            light
            full
            rounded
            style={{ padding: 10 }}
            onPress={() => Actions.login()}
          >
            <Icon type="FontAwesome" name="envelope" />
            <Text>Mon adresse email</Text>
          </Button>
          <Button
            full
            rounded
            style={{ padding: 10, marginTop: 20 }}
            onPress={() =>
              facebookLogin().then(() => {
                this.setState({ authentificated: true });
              })
            }
          >
            <Icon type="FontAwesome" name="facebook" />
            <Text style={{ color: "#fff" }}>Mon compte Facebook</Text>
          </Button>
        </Container>
      </LinearGradient>
    );
  }
}
const styles = StyleSheet.create({
  backgroundImage: {
    flex: 1,
    width: "100%",
    height: "100%",
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "transparent",
    padding: 25
  },
  logo: {
    width: 170,
    height: 130
  },
  loginText: {
    paddingTop: 50,
    paddingBottom: 50,
    color: "#fff"
  }
});

标签: react-native

解决方案


this.setState()应该从 React 组件内部调用。您在内部错误地调用它facebookLogin()loginUser()起作用。

你可以像这样修复它:

export async function loginUser(email, password) {
  try {
    return firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
  } catch (error) {
    console.log(error.toString);
  }
}

然后在您的组件中,您调用

  loginUser().then(() => {
    this.setState({ authentificated: true });
  });

但请确保您调用的方法this已正确绑定。通常的做法是定义这样的方法:

  renderCurrentState = () => {

  }

否则,您将不得不在组件的构造函数中进行绑定:

 constructor(props) {
    super(props);

    // ...
    this.renderCurrentState = this.renderCurrentState.bind(this);
  }

我所做的是改变loginUser()来回报一个承诺。然后你在你的组件中使用这个函数。

编辑:

您可以添加一个道具,例如。onLogin您可以在Login组件中使用它来更新已验证的状态。

  renderCurrentState() {
    if (this.state.authentificated) {
      return <Welcome />;
    } else {
      return <EmailLoging onLogin={this.updateState} />;
    }
  }

  updateState = () => {
    this.setState({ authentificated: true });
    // possibly other code

  }

onLogin你应该打电话loginUser().then(() => { ... })


推荐阅读