Реагировать Redux this.props всегда возвращать неопределенный - PullRequest
0 голосов
/ 21 июня 2019

Сейчас я нахожусь в React и делаю несколько приложений для изучения, узнайте больше о.И прямо сейчас я пытаюсь добавить информацию о зарегистрированном пользователе в состояние приведения, но когда я пытаюсь проверить значение 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';

Мой компонент RegistrationGoogle.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 ]

1 голос
/ 21 июня 2019

Это потому, что вы onClick метод-обработчик не привязан к экземпляру компонента, измените ваш конструктор следующим образом и ваши реквизиты больше не должны возвращать undefined:

constructor(props) {
    super(props);

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

В качестве альтернативы вы также можете изменить свой метод onClick, чтобы он выглядел следующим образом:

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

или превратите ваш метод обработчика onClick в функцию arrow :

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

, но первый вариант, использующий bind, является предпочтительным.

Обратитесь к документам для получения дополнительной информации об обработке событий.

EDIT:

Я пропустил, что была задействована другая функция обратного вызова. Вы получаете доступ к this.props из другой функции в обратном вызове signInWithPopup. Измените ваш обратный вызов на функцию стрелки, которая должна сохранить контекст метода signup и исправить вашу проблему:

firebase.auth().signInWithPopup(provider).then(result => {
    // ...
}).catch(error => {
    // ...
});
0 голосов
/ 22 июня 2019

Ваше определение регистрации в порядке, но вы можете просто обернуть его в функцию со стрелкой, которая имеет правильное значение "this".

OnClick = {() => регистрация ()}

0 голосов
/ 21 июня 2019

Все дело в контексте.Поскольку ваша функция signup связана с событием onclick, контекст this является <button>.

. Вы можете в конструкторе установить контекст this:

constructor(props) {
  super(props);

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

или используйте синтаксис стрелки:

signup = () => {

}

В документации React есть хороший ответ для привязки события: https://reactjs.org/docs/handling-events.html

...