我的功能组件有一个 useReducer 状态,它有两个输入,输入值设置为状态对象,状态在第一次渲染时完美运行,但是当我更改输入时,网页崩溃并且控制台错误说无法读取未定义的值 这是代码:
import React from "react";
import { useReducer } from "react";
import Card from "../UI/Card-Wrap/Card";
const Login = () => {
const reducer = (state, action) => {
if (action.id === "username") {
state.username = action.value;
}
if (action.id === "password") {
state.password = action.value;
}
};
const [state, dispatch] = useReducer(reducer, {
username: "",
password: "",
});
const onChangeHandler = (e) => {
dispatch(e.target);
};
return (
<div>
<Card>
<form action="#" className={Styles.form}>
<p>Login</p>
<div className={Styles.username}>
<label htmlFor="username">Username</label>
<input
type="text"
id="username"
onChange={onChangeHandler}
value={state.username}
/>
</div>
<div className={Styles.password}>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
onChange={onChangeHandler}
value={state.password}
/>
</div>
<button type="submit">Submit</button>
</form>
</Card>
</div>
);
};
export default Login;
我试图找到它在每个渲染器上发生的位置,显然每次我在 Reducer 函数中设置状态值时都会发生。
问题发生是因为你的reducer函数没有返回新状态。
这会导致在您发送操作后状态为
undefined
,然后在输入 cannot read value of undefined
属性时引发 value
错误。
根据 React 文档:
状态是只读的。不要修改状态中的任何对象或数组:
function reducer(state, action) { switch (action.type) { case 'incremented_age': { // 🚩 Don't mutate an object in state like this: state.age = state.age + 1; return state; }
相反,总是从你的减速器返回新对象:
function reducer(state, action) { switch (action.type) { case 'incremented_age': { // ✅ Instead, return a new object return { ...state, age: state.age + 1 }; }
请注意,除了返回状态,它应该是一个新对象。
您不应该更改当前状态对象中的值,因为 JS 中的对象被视为 references 并且通过返回相同的状态对象,React 不会重新渲染您的组件。
所以,问题的解决方案可以重写 reducer 函数如下:
const reducer = (state, action) => {
switch (action.id) {
case "username":
return {
...state, // Spreads the current state into a new object
username: action.value, // and changes only the desired value
};
case "password":
return {
...state,
password: action.value,
};
default:
return { ...state };
}
};