React Redux this.props总是返回undefined

时间:2019-06-21 19:54:34

标签: javascript reactjs redux react-redux undefined

我现在在React从事一些应用程序的研究,以了解更多信息。现在,Aand我正在尝试将记录的用户信息添加到redux状态,但是当我尝试检查this.props.user的值时,我的应用程序总是返回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登录后,我可以在浏览器日志中看到以下内容:

console.log after login with Google firebase

3 个答案:

答案 0 :(得分:1)

那是因为您的onClick处理程序方法未绑定到组件实例,请像这样修改构造函数,并且道具应不再返回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

编辑:

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

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

答案 1 :(得分:0)

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

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

constructor(props) {
  super(props);

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

或使用箭头语法:

signup = () => {

}

反应文档在这里为事件绑定提供了很好的答案:https://reactjs.org/docs/handling-events.html

答案 2 :(得分:-1)

您的注册定义很好,但是您可以将其包装在具有正确“ this”值的箭头函数中。

onClick = {()=> signup()}