【发布时间】:2018-03-30 19:53:45
【问题描述】:
我正在为 Web 应用程序构建身份验证,当我将登录数据发送到服务器时卡住了,但我无法异步执行,因为我创建的函数不返回承诺。
所以我想要完成的是当我填写表单时按下按钮并执行函数 onSubmit(),它验证输入的数据,然后如果一切正常,则执行传递的函数 submit()。然后函数 submit() 执行 api.user.login(data) 函数,将数据发送到服务器并接收有关用户注册状态的信息。如果登录状态为成功,用户将被重定向到用户页面,但是当调用 api.user.login() 时我被卡住了,它不返回承诺。
当我提交表单数据时,出现如下错误。但是服务器仍然接收表单数据。
TypeError: Cannot read property 'then' of undefined
LoginPage._this.submit
src/components/pages/LoginPage.js:17
14 | }
15 |
16 | submit = data => {
> 17 | api.user.login(data)
18 | .then(res => {
19 | if (res.data === "loginSucces") {
20 | <Redirect to="/user"/>
View compiled
LoginForm._this.onSubmit
src/components/pages/forms/LoginForm.js:26
23 |
24 | //is empty method or ES6 Object.keys(errs) takes all the keys
25 | if (Object.keys(errors).length === 0) {
> 26 | this.props.submit(this.state.data)
27 | // console.log("hello");
28 | // this.props.submit()
29 | }
我试图做的是将登录函数包装在 new Promise() 中,但这绝对行不通。
return new Promise((resolve, rejec) => {
let data = JSON.stringify(credentials);
axios.post("/register", data
).then(function(res) {
console.log(res);
return res.data
}).catch(function(error) {
console.log(error);
});
})
所以我的登录页面代码如下:
import React from 'react';
import LoginForm from './forms/LoginForm';
import PropTypes from "prop-types"
import api from "../../api.js"
import { Route, Redirect } from 'react-router'
class LoginPage extends React.Component
{
constructor(){
super();
this.state = {
};
}
submit = data => {
api.user.login(data).then(res => {
if (res === "loginSucces") {
<Redirect to="/user"/>
}
}).cache(err=>{
console.error(err);
})
}
render() {
return (
<div>
<h1>Login page</h1>
<LoginForm submit={this.submit}/>
</div>
);
}
}
export default LoginPage;
登录表单代码:
import React from 'react';
import PropTypes from "prop-types";
import {Button, Form, FormGroup, Label, Input, FormFeedback} from 'reactstrap';
class LoginForm extends React.Component{
constructor(){
super();
this.state = {
data:{},
loading: false,
errors: {}
};
}
onChange = e =>
this.setState({
data: {...this.state.data, [e.target.name]: e.target.value}})
onSubmit = e => {
e.preventDefault();
const errors = this.validate(this.state.data);
this.setState({ errors: errors })
//is empty method or ES6 Object.keys(errs) takes all the keys
if (Object.keys(errors).length === 0) {
this.props.submit(this.state.data)
// console.log("hello");
// this.props.submit()
}
}
validate = (data) => {
const errors = {};
//TODO cant be special sibols, to short etc
if(!data.username) {
errors.username = "Can't be bank";
}
if(!data.password){
errors.password = "Can't be bank";
}
return errors;
}
render() {
return(
//TODO form still reloads
<Form onSubmit={this.onSubmit}>
<FormGroup>
<Label for="username">Username</Label>
<Input
invalid={!!this.state.errors.username}
name="username"
id="username"
placeholder="What is your username?"
value = {this.state.data.username}
onChange = {this.onChange}
/>
<FormFeedback invalid >{this.state.errors.username}</FormFeedback>
</FormGroup>
<FormGroup>
<Label for="password">Password</Label>
<Input invalid={!!this.state.errors.password}
type="password"
name="password"
id="password"
placeholder="Make it secure"
value = {this.state.data.password}
onChange = {this.onChange}
/>
<FormFeedback invalid >{this.state.errors.password}</FormFeedback>
</FormGroup>
<Button preventDefault>Submit</Button>
</Form>
)
}
}
LoginForm.propTypes = {
submit: PropTypes.func.isRequired
};
export default LoginForm;
API 代码:
import axios from "axios"
export default {
user: {
login: credentials =>{
let data = JSON.stringify(credentials);
axios.post("/register", data
).then(function(res) {
console.log(res);
return res.data
}).catch(function(error) {
console.log(error);
});
},
test: () => {console.log("test in api")}
}
}
这是 console.log(res) 输出:
{
data: "loginSucces",
status: 200,
statusText: "OK",
headers: {
…
},
config: {
…
},
…
}config: adapter: ƒxhrAdapter(config)arguments: (...)caller: (...)length: 1name: "xhrAdapter"prototype: {
constructor: ƒ
}__proto__: ƒ()[
[
FunctionLocation
]
]: xhr.js: 11[
[
Scopes
]
]: Scopes[
2
]data: "{"username":"sdfsdfdfsdfsdfsdgsdfgsdgsadgsdgsdag","password":"sdfsdfsdfsdf345235235"}"headers: Accept: "application/json, text/plain, */*"Content-Type: "application/x-www-form-urlencoded"__proto__: ObjectmaxContentLength: -1method: "post"timeout: 0transformRequest: {
0: ƒ
}transformResponse: {
0: ƒ
}url: "/register"validateStatus: ƒvalidateStatus(status)xsrfCookieName: "XSRF-TOKEN"xsrfHeaderName: "X-XSRF-TOKEN"__proto__: Objectdata: "loginSucces"headers: connection: "close"content-length: "11"content-type: "text/html; charset=utf-8"date: "Fri, 30 Mar 2018 20:03:56 GMT"etag: "W/"b-JeyKc7pdZbjTvd8ActAidnhWojA""vary: "Accept-Encoding"x-powered-by: "Express"__proto__: Objectrequest: XMLHttpRequestonabort: nullonerror: ƒhandleError()onload: nullonloadend: nullonloadstart: nullonprogress: nullonreadystatechange: ƒhandleLoad()ontimeout: ƒhandleTimeout()readyState: 4response: "loginSucces"responseText: "loginSucces"responseType: ""responseURL: "http://localhost:3000/register"responseXML: nullstatus: 200statusText: "OK"timeout: 0upload: XMLHttpRequestUploadonabort: nullonerror: nullonload: nullonloadend: nullonloadstart: nullonprogress: nullontimeout: null__proto__: XMLHttpRequestUploadwithCredentials: false__proto__: XMLHttpRequeststatus: 200statusText: "OK"__proto__: constructor: ƒObject()hasOwnProperty: ƒhasOwnProperty()isPrototypeOf: ƒisPrototypeOf()propertyIsEnumerable: ƒpropertyIsEnumerable()toLocaleString: ƒtoLocaleString()toString: ƒtoString()valueOf: ƒvalueOf()__defineGetter__: ƒ__defineGetter__()__defineSetter__: ƒ__defineSetter__()__lookupGetter__: ƒ__lookupGetter__()__lookupSetter__: ƒ__lookupSetter__()get__proto__: ƒ__proto__()set__proto__: ƒ__proto__()
【问题讨论】:
-
console.log(res)收到的回复是什么? -
刚刚检查,对服务器的请求工作正常,我可以将表单数据发送到服务器,服务器发回确认。
-
请参阅已编辑的问题。
-
将此行
if (res === "loginSucces")更改为if (res.data === "loginSucces") -
是的,这是一个错误,但它不会影响这个问题,因为如果没有承诺,我不能使用 .then()。
标签: javascript reactjs api asynchronous login