每当我在
useEffect钩子的帮助下更改密码时,我都会尝试打印状态
value
的值。虽然它运行良好,但每当我尝试更改 email
时,email
的值也会在控制台中呈现
useEffect(() => {
console.log(values);
}, [values.password]);
但根据我的逻辑,只有在
password
的值发生变化时才应该渲染。
正如我所标记的,每当我更改
email
的值时,它们都不能显示,因为它们正在渲染
以下是我的代码
Form.js
import { useState } from "react";
export const useForm = (initialValues) => {
const [values, setValues] = useState(initialValues);
return [
values,
(e) => {
setValues({
//...values,
[e.target.name]: e.target.value,
});
},
];
};
App.js
import "./App.css";
import { useState, useEffect } from "react";
import { useForm } from "./Form";
const App = () => {
const [values, handelChange] = useForm({ email: "", password: "" });
useEffect(() => {
console.log(values);
}, [values.password]);
return (
<div className="field">
<input
type="email"
name="email"
value={values.email}
onChange={handelChange}
/>
<input
type="password"
name="password"
value={values.password}
onChange={handelChange}
/>
</div>
);
};
export default App;
您唯一需要更改的是删除
values
钩子上注释的 useForm
-析构:
return [
values,
(e) => {
setValues({
...values, // remove the comment from your code in the question!!
[e.target.name]: e.target.value,
});
},
];
};
注释导致密码被从每个电子邮件输入的新
password
对象中删除(您可以在值上调用属性 undefined
,但您会得到 values
)。在日志中,您可以看到这一点,但正如您所描述的,仅一次!
此外,我会将您的
useForm
钩更改为:
const useForm = (initialValues) => {
const [values, setValues] = useState(initialValues);
return [
values,
(e) => {
setValues(prevValues => {
return {
...prevValues,
[e.target.name]: e.target.value,
}
});
}
];
};
如果新状态是使用先前状态计算的,则应使用 params 中的先前状态。 React 状态更新可以批量进行,不以这种方式编写更新可能会导致意外结果。