因此即时通讯正在为我的项目准备redux并陷入困境。 一切似乎都正确,因为redux devtools显示了状态。
当我尝试通过this.props.function_name
调用组件中的函数时,会出现问题我在.then()中执行该调用,因为当axios返回令牌时正在调用它,我知道此范围会在那时发生变化,但是我当时正在使用arrow函数,因此问题似乎不存在
也尝试从另一个函数调用this.props.setcurrent,但是得到了 _this2未定义 我的代码:
Signup.js
import {setCurrent} from '../actions/authActions'
class SignUp extends Component {
constructor(props) {
super(props);
}
responseGoogle(response) {
console.log('google', response);
const access_token = response.Zi.access_token;
axios
.post('http://localhost:3001/users/oauth/google', {
access_token
})
.then((response) =>{
console.log('google', response);
const decoded = jwt_decode(response.data.token);
this.props.setCurrent(decoded);
console.log(decoded);
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<GoogleLogin
clientId="890644813294-bvuq6cf7lsilohneqvov28oi60sfdmig.apps.googleusercontent.com"
buttonText="Login"
onSuccess={this.responseGoogle}
onFailure={this.responseGoogle}
/>
)
}
}
export default connect(null, { setCurrent })(SignUp);
authActions.js
import { TEST_DISPATCH } from './types';
// Testing
export const setCurrent = (userToken) => {
return {
type: TEST_DISPATCH,
payload: userToken
};
};
authReducer.js
import { TEST_DISPATCH } from '../actions/types';
const initialState = {
isAuthenticated: false,
user: {}
}
export default function(state = initialState, action) {
switch(action.type) {
case TEST_DISPATCH:
return {
...state,
user: action.payload
};
default:
return state;
}
}
Auth / index.js
import { combineReducers } from 'redux';
import authReducer from './authReducer';
export default combineReducers({
auth: authReducer
});
store.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
// window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
App.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import store from '../store';
import LogIn from './LogIn';
import SignUp from './SignUp';
class App extends Component {
render() {
return(
<Provider store={ store }>
<div>
<h1>SignUp!</h1>
<SignUp />
</div>
</Provider>
)
}
}
export default App;
完整代码:https://github.com/ExadelPraktika/Front-exabook/tree/auth 我也在webpack上使用babel
答案 0 :(得分:3)
我知道那时范围会发生变化,但是我当时使用的是箭头功能,因此问题似乎不存在。
这仍然是一个范围问题。方法responseGoogle是作用域的。因此,您需要像这样“自动绑定”它:
responseGoogle = (response) => { /* Your code */ }
或:SignUp组件的呈现方法:
<GoogleLogin
onSuccess={response => this.responseGoogle(response)}
onFailure={response => this.responseGoogle(response)}
/>
答案 1 :(得分:1)
您对this
的引用错误上下文的想法是正确的。在查看此代码段时,我添加了一些注释,这些注释可能有助于澄清。
class SignUp extends Component {
constructor(props) {
super(props);
}
responseGoogle(response) {
// "this" does not refer to the class instance here when invoked by
// the click handler (it is undefined)
const access_token = response.Zi.access_token;
axios
.post('http://localhost:3001/users/oauth/google', {
access_token
})
.then((response) => {
// Because this is a lambda function, "this" is the same lexical scope
// as the outer function - but the outer function "this" is undefined
// *not* the instance of the class (see above)
const decoded = jwt_decode(response.data.token);
this.props.setCurrent(decoded);
console.log(decoded);
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<GoogleLogin
clientId="890644813294-bvuq6cf7lsilohneqvov28oi60sfdmig.apps.googleusercontent.com"
buttonText="Login"
onSuccess={this.responseGoogle}
onFailure={this.responseGoogle}
/>
)
}
}
有两种常见的解决方法:
在构造函数中使用bind
class SignUp extends Component {
constructor(props) {
super(props);
this.responseGoogle = this.responseGoogle.bind(this);
}
responseGoogle(response) {
const access_token = response.Zi.access_token;
axios
.post('http://localhost:3001/users/oauth/google', {
access_token
})
.then((response) => {
// Because this is a lambda function, "this" is the same lexical scope
// as the outer function - but the outer function "this" is undefined
// *not* the instance of the class (see above)
const decoded = jwt_decode(response.data.token);
this.props.setCurrent(decoded);
console.log(decoded);
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<GoogleLogin
clientId="890644813294-bvuq6cf7lsilohneqvov28oi60sfdmig.apps.googleusercontent.com"
buttonText="Login"
onSuccess={this.responseGoogle}
onFailure={this.responseGoogle}
/>
)
}
}
JavaScript的bind方法存在于函数中,并返回一个与原始函数相同的新函数,但其上下文(其“ this”)设置为传递给bind
的任何东西。因此,我们创建了一个新方法,该方法绑定到构造函数中的任何“ this”。在构造函数中,“ this”是类实例,因此在点击处理程序中也是如此。
使用lambda函数代替类方法
class SignUp extends Component {
responseGoogle = (response) => {
const access_token = response.Zi.access_token;
axios
.post('http://localhost:3001/users/oauth/google', {
access_token
})
.then((response) =>{
console.log('google', response);
const decoded = jwt_decode(response.data.token);
this.props.setCurrent(decoded);
console.log(decoded);
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<GoogleLogin
clientId="890644813294-bvuq6cf7lsilohneqvov28oi60sfdmig.apps.googleusercontent.com"
buttonText="Login"
onSuccess={this.responseGoogle}
onFailure={this.responseGoogle}
/>
)
}
}
由于保持外部“ this”的原因,对.then
的lambda函数回调起作用的原因相同。该方法的唯一缺点是它不是JS语言的真正组成部分,因此您需要进行翻译才能使其正常工作(但是您已经在使用babel / webpack了,所以这不是问题)