无法使用从 Axios 收到的数据在 React Hooks 中设置状态
2020-07-29
1209
我正在使用 React Hooks 创建登录表单并使用 Axios 查询后端。成功登录后,我将重定向到正常运行的主页。问题在于尝试失败时,我想将 loginFailed 设置为 true,并基于此对表单进行条件渲染。 但不幸的是 setLoginFailed 不起作用。
这是我在客户端执行的操作:
import React, { useState } from "react"
import { useForm } from "react-hook-form"
import { useHistory } from "react-router-dom";
import { yupResolver } from '@hookform/resolvers'
import * as yup from "yup"
import axios from 'axios'
import './Login.css'
const schema = yup.object().shape({
username: yup.string().required("Please enter Username."),
password: yup.string().required("Please enter Password.")
})
export default function Login() {
const [loginFailed, setLoginFailed] = useState(null);
const { register, handleSubmit, errors } = useForm({
resolver: yupResolver(schema)
})
const history = useHistory();
const onSubmit = data => {
axios.post('/login', data)
.then((response) => {
if (response.data.success) {
history.push("/")
} else {
setLoginFailed(true)
}
})
}
return (
<form className="login-form" onSubmit={handleSubmit(onSubmit)}>
{loginFailed && <p>Invalid Username/Password.</p>}
<input type="text" name="mobile" placeholder="Mobile Number" ref={register} />
<p className="error">{errors.mobile?.message}</p>
<input type="password" name="password" placeholder="Password" ref={register} />
<p className="error">{errors.password?.message}</p>
<input type="submit" value="Login" />
</form>
)
}
以及在服务器端执行的操作:
var express = require('express')
var router = express.Router()
var passport = require('passport')
var Farmer = require('../models/farmer')
router.post('/login', function(req, res, next) {
console.log(req.body)
passport.authenticate('local', function(err, user, info) {
if (err) {
return res.json({success: false})
}
if (!user) {
return res.json({success: false})
}
req.logIn(user, function(err) {
if (err) {
return res.json({success: false})
}
return res.json({success: true})
})
})(req, res, next)
})
module.exports = router
我做错了什么?如何在客户端正确设置我的状态?
2个回答
我在本地重新创建了您的应用,一切看起来都很好,除了您用于“手机号码”输入的名称。在您的
yup
架构中,您有
username
,而输入的名称是
mobile
。因此,您必须将其中一个更改为另一个。
在我的示例中,这意味着
yup
认为提交无效,并且从未向 API 提交任何内容。除非问题中的代码与您的实际代码不同,否则
onSubmit
永远不会发生。我很好奇您的代码是如何进入
axios.then
的。
无论如何,这是一个有效示例:
App.js
:
import React, { useState } from "react"
import { useForm } from "react-hook-form"
import { useHistory } from "react-router-dom";
import { yupResolver } from '@hookform/resolvers'
import * as yup from "yup"
import axios from 'axios'
const schema = yup.object().shape({
username: yup.string().required("Please enter Username."),
password: yup.string().required("Please enter Password.")
})
export default function Login() {
const [loginFailed, setLoginFailed] = useState(false);
const { register, handleSubmit, errors } = useForm({
resolver: yupResolver(schema)
})
const history = useHistory();
const onSubmit = data => {
axios.post('http://0.0.0.0:5000/login', data)
.then((response) => {
if (response.data.success) {
history.push("/")
} else {
setLoginFailed(true)
}
})
.catch(console.log)
}
return (
<form className="login-form" onSubmit={handleSubmit(onSubmit)}>
{loginFailed && <p>Invalid Username/Password.</p>}
<input type="text" name="username" placeholder="Mobile Number" ref={register} />
<p className="error">{errors.mobile?.message}</p>
<input type="password" name="password" placeholder="Password" ref={register} />
<p className="error">{errors.password?.message}</p>
<input type="submit" value="Login" />
</form>
)
}
server.js
:
const cors = require('cors')
var express = require('express')
var router = express.Router()
router.post('/login', function(req, res, next) {
return res.json({ success: false })
})
var app = express()
app.use(cors())
app.options('*', cors())
app.use('/', router)
app.listen(5000, () => {
console.log(`Example app listening at http://localhost:${5000}`)
})
请注意,我在
axios.post
中添加了
catch
来处理错误,并且没有重新创建
passport
内容,只是返回
{success: false
来测试代码。
此外,正如评论中提到的那样,最好使用
false
而不是
null
来初始化布尔状态。
kaveh
2020-08-04
问题在于使用表单标签。
您需要修改表单提交操作为
const handleFormSubmit = (e) => {
e.preventDefault();
handleSubmit(onSubmit);
}
<form className="login-form" onSubmit={(e) => handleFormSubmit(e)}>
...
...
</form>
默认情况下,表单提交操作会触发重新加载操作,这会导致您出现问题。
groot
2020-08-07