React Redux this.props 始终 return 未定义

React Redux this.props always return undefined

我现在在 React,我正在做一些应用程序来学习,了解更多。现在我正在尝试将记录的用户信息添加到 redux 状态,但是当我尝试检查 this.props.user 的值时,我的应用程序总是 returns undefined.

我的reducer.js

import { LOG_USER } from '../actions/actions';

let initialState = {
  user: {
    userName: '',
    imageUrl: ''
  }
}

const userInfo = (state = initialState, action) => {
  switch (action.type) {
    case LOG_USER:
      return {
        ...state,
        user: action.user
      };
    default:
      return state;
  }
}

const reducers = userInfo;

export default reducers;

我的actions.js

export const LOG_USER = 'LOG_USER';

我的SignupGoogle.js组件:

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';
import firebase from '../../config/firebase';

import { connect } from 'react-redux'
import { LOG_USER } from '../../actions/actions';

import './SignupGoogle.css'

class SignupGoogle extends Component {
  constructor(props) {
    super(props);
  }
  signup() {
    let provider = new firebase.auth.GoogleAuthProvider();
    firebase.auth().signInWithPopup(provider).then(function(result) {
      console.log('---------------------- USER before login')
      console.log(this.props.user)
      let user = {
        userName: result.user.providerData[0].displayName,
        imageUrl: result.user.providerData[0].photoURL
      }
      console.log(user)
      this.props.logUser(user)
      console.log('---------------------- USER after login')
      console.log(this.props.user)
    }).catch((error) => {
      console.log(error.code)
      console.log(error.message)
      console.log(error.email)
    })
  }
  render() {
    return (
      <Button onClick={this.signup} variant="contained" className="btn-google">
        Sign Up with Google
        <img className='imgGoogle' alt={"google-logo"} src={require("../../assets/img/search.png")} />
      </Button>
    );
  }
}

const mapStateToProps = state => {
  return {
    user: state.user
  };
}

const mapDispatchToProps = dispatch => {
  return {
    logUser: (user) => dispatch({type: LOG_USER, user: user})
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(SignupGoogle);

还有我的index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { BrowserRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux'
import { createStore } from 'redux';
import reducers from './reducers/reducers';

const store = createStore(reducers)

ReactDOM.render(
  <Provider store={store}>
    <Router>
      <App />
    </Router>
  </Provider>,
  document.getElementById('root')
);

serviceWorker.unregister();

这是我在使用 Google firebase 登录后在浏览器日志中可以获得的内容:

那是因为你 onClick 处理程序方法没有绑定到组件的实例,像这样修改你的构造函数,你的道具不应该再 return undefined:

constructor(props) {
    super(props);

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

或者,您也可以将 onClick 方法修改为如下所示:

<Button onClick={() => this.signup()} variant="contained" className="btn-google">

或将您的 onClick 处理程序方法转换为 arrow function:

signup = () => {
    // ...
}
...
<Button onClick={this.signup} variant="contained" className="btn-google">

但是使用 bind 的第一个选项是首选。

有关事件处理的更多信息,请参阅 docs

编辑:

我错过了涉及另一个回调函数。 您正在从 signInWithPopup 回调中的另一个函数内访问 this.props。将您的回调更改为箭头函数,它应该保留 signup 方法的上下文并解决您的问题:

firebase.auth().signInWithPopup(provider).then(result => {
    // ...
}).catch(error => {
    // ...
});

一切都与上下文有关。由于您的 signup 函数绑定到 onclick 事件,因此 this 上下文是 <button>.

您可以在构造函数中设置 this 上下文:

constructor(props) {
  super(props);

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

或使用箭头语法:

signup = () => {

}

React 文档在这里对事件绑定有很好的回答:https://reactjs.org/docs/handling-events.html

您的注册定义很好,但您可以将其包装在具有适当 'this' 值的箭头函数中。

onClick={()=>注册()}