![](/img/trans.png)
[英]How to use the UseState hook as the name of a property in an object?
[英]React useState hook: object property remains unchanged
我最近開始學習 react 並且我有一個包含登錄表單的組件:
import Joi from "joi";
import { useState } from "react";
const Login = () => {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const loginSchema = Joi.object().keys({
username: Joi.string().required(),
password: Joi.string().required(),
});
const [errors, setErrors] = useState({ username: null, password: null });
const handleSubmit = (form) => {
form.preventDefault();
validate();
};
const validate = () => {
const { error } = loginSchema.validate(
{ username, password },
{ abortEarly: false }
);
if (!error) return null;
for (const item of error.details) {
let key = item.path[0];
let value = item.message;
setErrors({ ...errors, [key]: value });
}
return errors;
};
return (
<div className="container">
<div>
<h1>Login</h1>
</div>
<div className="card">
<div className="card-body">
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="username">Username</label>
<input
name="username"
type="text"
className="form-control"
id="username"
placeholder="Enter username"
value={username}
onChange={(username) => setUsername(username.target.value)}
/>
{errors.username && (
<div className="alert alert-danger">{errors.username}</div>
)}
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input
name="password"
type="password"
className="form-control"
id="password"
placeholder="Password"
value={password}
onChange={(password) => setPassword(password.target.value)}
/>
{errors.password && (
<div className="alert alert-danger">{errors.password}</div>
)}
</div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
{/* Delete later */}
<h4>{JSON.stringify(errors)}</h4>
</div>
</div>
</div>
);
};
export default Login;
在這里,我試圖在錯誤 object 中設置用戶名和密碼的值,但由於某種原因,只設置了密碼屬性,用戶名屬性仍然是 null。 我已經使用 object 解構但它仍然沒有設置值,請幫助。
我認為問題來自這段代碼
for (const item of error.details) {
let key = item.path[0];
let value = item.message;
setErrors({ ...errors, [key]: value });
}
在這里,您在 for 循環中調用setErrors
時出現相同的errors
object 因此只考慮最后一個字段。
這是一個可能的解決方案:
if (!error) return null;
const newErrors = error.details.reduce((acc, item) => {
const key = item.path[0];
const value = item.message;
acc[key] = value;
return acc;
}, {...errors});
setErrors(newErrors);
State 更新不會立即反映在 React 中,並且由於您循環數據以設置錯誤 object 多次,由於事件處理程序中的批處理以及 Z9ED39E2EA9312586B6AZ85E 更新受閉包影響的事實,它僅設置在最后一個鍵中。
您應該創建一個更新的對象並將其設置在 state 一次
let newErrors = {};
for (const item of error.details) {
let key = item.path[0];
let value = item.message;
newErrors = { ...newErrors, [key]: value };
}
setErrors(prev => ({...prev, ...newErrors}));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.