我有一个名为 doLogin() 的 MobX 操作。它能够this.在发出 HTTP 请求之前访问,但一旦发出 HTTP 请求,它就会变成undefined. 我一直在尝试箭头函数、绑定等的不同迭代大约 4 个小时,并开始失去理智。
我尝试过使用不同的 HTTP 请求库 ( axios, request) 以及 Fetch API。都产生相同的结果。
runInAction()即使我没有启用严格模式,我也尝试过使用 MobX实用程序。结果相同。
AuthStore.js
import { observable, action } from "mobx";
import axios from "axios";
class AuthStore {
@observable token = "";
@observable isLoggedIn = false;
@observable loading = false;
@observable error = null;
@action setToken = (token) => {
this.token = token;
this.isLoggedIn = true;
this.loading = false;
}
@action doLogin = (email, password) => {
this.loading = true; // works as expected
console.log("this before: ", this); // prints AuthStore
axios.post('http://my-api.com/users/authenticate', {
email: email,
password: password
})
.then(function (response) {
console.log("this after: ", this); // prints undefined
this.setToken(response.data.response.token); // err
})
.catch(function (error) {
console.log("Auth store error ", error);
});
}
}
const store = new AuthStore();
export default store;
登录.js
import React from "react";
import { Form, Input, Button, Checkbox } from 'antd';
import { inject, observer } from 'mobx-react';
import "./Login.less";
@inject('AuthStore')
@observer
export default class Login extends React.Component {
componentDidMount() {
// To disabled submit button at the beginning.
this.props.form.validateFields();
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
this.props.AuthStore.doLogin(values.email, values.password);
}
});
}
hasErrors = (fieldsError) => {
return Object.keys(fieldsError).some(field => fieldsError[field]);
}
render() {
const { loading } = this.props.AuthStore;
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;
const emailError = isFieldTouched('email') && getFieldError('email');
const passwordError = isFieldTouched('password') && getFieldError('password');
return (
<div id="login">
<Form onSubmit={this.handleSubmit} className="login-form">
<Form.Item validateStatus={emailError ? 'error' : ''} help={emailError || ''}>
{getFieldDecorator('email', {
rules: [{ required: true, message: 'Please input your email!' }],
})(
<Input prefix={<i className="far fa-user"></i>} placeholder="Username" />
)}
</Form.Item>
<Form.Item validateStatus={passwordError ? 'error' : ''} help={passwordError || ''}>
{getFieldDecorator('password', {
rules: [{ required: true, message: 'Please input your Password!' }],
})(
<Input prefix={<i className="far fa-lock"></i>} type="password" placeholder="Password" />
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('remember', {
valuePropName: 'checked',
initialValue: true,
})(
<Checkbox>Remember me</Checkbox>
)}
<a className="login-form-forgot" href="">Forgot password</a>
<Button type="primary" htmlType="submit" className="login-form-button" loading={loading} disabled={this.hasErrors(getFieldsError())}>
Log in
</Button>
Don't have an account? <a href="">Register now!</a>
</Form.Item>
</Form>
</div>
);
}
}
Login = Form.create({})(Login);
在我收到 API 的响应后,我希望能够在我的操作中调用 this.setToken(response.data.response.token),但我不能。
编辑:
我使用$this=this. 不确定这是否是解决问题的正确方法,但这只是一个个人项目,在已经在这个功能上浪费了几个小时之后,我已经结束了。
所以现在看起来像
@action doLogin = (email, password) => {
const $this = this
this.loading = true; // works as expected
axios.post('http://my-api.com/users/authenticate', {
email: email,
password: password
})
.then(function (response) {
$this.setToken(response.data.response.token);
})
.catch(function (error) {
console.log("Auth store error ", error);
});
}