【问题标题】:Getting React.createElement: type is invalid when using setState获取 React.createElement:使用 setState 时类型无效
【发布时间】:2017-07-20 15:30:33
【问题描述】:

预期

在不输入邮箱或密码的情况下点击登录按钮后,用户应该会看到通知组件

结果

点击登录后,调用setState设置this.state.errors为true,并显示上述错误信息。

handleSubmit 函数

如果我删除下面的 this.setState 行,什么都不会发生,但我不会收到任何 Chrome 错误。但是我需要setState,这样我就可以使用它来显示通知(请参阅此块下方的代码)

handleLoginSubmit = this.handleLoginSubmit.bind(this);
handleLoginSubmit(e, user) {
  e.preventDefault();
  if (R.isNil(user.email)) return;

  // Log user in via Firebase
  firebase.auth().signInWithEmailAndPassword(user.email, user.password)
    .catch((err) => {
      if (err.code === 'auth/user-not-found') {
        console.log('need to create user')
        return this.createUser(user.email, user.password);
      } else {
        console.log('Incorrect email or password, please try again')

        this.setState({
          errors: true,
          errorMsg: 'Incorrect email or password, please try again'
        }, function () {
          console.log('>>> this.state', this.state);
        });
      }

      console.log('Completed')
    })
}

设置状态后我也看不到console.log:


render() {
  return (
    <main>
      { this.state.errors ? <Notification/> : null }
      <Login handleLoginSubmit={ this.handleLoginSubmit }
             email={ this.state.email }
             password={ this.state.password } />
    </main>
  )
}

完整代码

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import * as R from 'ramda'
import * as firebase from 'firebase'

import { Login } from '../../components'
import { Notification } from '../../components'

export class LoginX extends Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            password: '',
            errors: false,
            errorMsg: ''
        }
        this.handleLoginSubmit = this.handleLoginSubmit.bind(this);
    }

    componentDidMount() {
    firebase.auth().onAuthStateChanged((user) => {
      this.checkAuth();
    })
  }

    componentDidUpdate(prevProps, prevState) {
      console.log('componentDidUpdate this.state', this.state)
    }

    checkAuth() {
    const user = firebase.auth().currentUser;

    if (!user) {
      return
    }
    else {
      if (!user.emailVerified) {
        // User has signed up, redirect them to verification
        this.props.history.push('/verification');
        return
      }
    }

    // User does not need to be authenticated.
    this.props.history.push('/dashboard');
  }

    handleLoginSubmit(e, user) {
        e.preventDefault();
        if (R.isNil(user.email)) return;

        // Log user in via Firebase
        firebase.auth().signInWithEmailAndPassword(user.email, user.password)
      .catch((err) => {
        if (err.code === 'auth/user-not-found') {
          console.log('need to create user')
          return this.createUser(user.email, user.password);
        }
        else {
          console.log('Incorrect email or password, please try again')

          this.setState({
            errors: true,
            errorMsg: 'Incorrect email or password, please try again'
          }, function() {
            console.log('>>> this.state', this.state);
          });
        }

        console.log('Completed')
      })
    }

    createUser(user, pass) {
    firebase.auth().createUserWithEmailAndPassword(user, pass)
      .then((user) => {
        console.log('verification email sent')
        // user.sendEmailVerification()
      })
      .catch((err) => {
        console.log(err)
        // this.setState({inProgress: false})
        switch (err.code) {
          case "auth/email-already-in-use": {
                        console.log('Account already exists, please log in')
            // this.setState({errorMsg: "Account already exists, please log in"});
            break;
          }
          case "auth/invalid-email": {
                        console.log('Invalid email address format (domain is automatically included)')
            // this.setState({errorMsg: "Invalid email address format (domain is automatically included)"});
            break;
          }
          case "auth/operation-not-allowed": {
                        console.log('Login system in unavailable, please contact the system administrator')
            // this.setState({errorMsg: "Login system in unavailable, please contact the system administrator"});
            break;
          }
        }
      })
  }

    render() {
        return (
            <main>
                { this.state.errors ? <Notification/> : null }
                <Login handleLoginSubmit={ this.handleLoginSubmit }
                       email={ this.state.email }
                       password={ this.state.password } />
            </main>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        state
    }
}


const LoginContainer = LoginX;
export default connect(mapStateToProps)(withRouter(LoginContainer))

通知有问题

import React from 'react'
import PropTypes from 'prop-types'

const Notifications = (props) => {

  return (
    <div className="notification">
      Notifications
    </div>
  );
}

export default Notifications

Notifications.propTypes = {

};

【问题讨论】:

  • 哦,我必须像这样导出类LoginX 并导出默认LoginContainer,这样我的测试才能通过。 LoginContainer 包含不可测试的存储。所以在我的测试中,我测试了LoginX
  • 在点击按钮之前一切正常吗?
  • @MayankShukla 是的,如果我删除 setState 行也没有错误,但当然我不能显示通知组件。

标签: javascript reactjs setstate


【解决方案1】:

我认为这是一个错字,请使用 Notifications 而不是 Notification

import { Notifications } from '../../components';

【讨论】:

  • 嘿嘿,有时会发生这种情况,我认为你需要休息 :)
猜你喜欢
  • 2017-12-22
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 2018-07-22
  • 2019-08-19
  • 2021-02-24
  • 1970-01-01
  • 2023-03-10
相关资源
最近更新 更多