我现在在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登录后,我可以在浏览器日志中看到以下内容:
答案 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()}