NextJS - 将类函数转换为钩子函数时,未处理的运行时错误 TypeError:无法读取未定义的属性(读取“长度”)
2022-08-01
1487
我尝试将类函数文件转换为钩子函数,但每当在字段中输入文本时都会出现以下错误。
Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'length')
我想我已经转换了所有内容,但就是找不到是什么 - 我遗漏了什么吗?
新的钩子代码出现上述错误:
import React, { useState } from "react";
function Todo(props) {
const [state, setState] = useState({ items: [], text: "" });
const handleChange = (e) => {
setState({ text: e.target.value });
};
const handleSubmit = (e) => {
e.preventDefault();
if (state.text.length === 0) {
return;
}
const newItem = {
text: state.text,
id: Date.now(),
};
setState((state) => ({
items: state.items.concat(newItem),
text: "",
}));
};
return (
<div>
<form onSubmit={handleSubmit}>
<label htmlFor="new-todo">What needs to be done?</label>
<input id="new-todo" onChange={handleChange} value={state.text} />
<button>Add #{state.items.length + 1}</button>
</form>
<TodoList items={state.items} />
</div>
);
}
function TodoList(props) {
return (
<ul>
{props.items.map((item) => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
export default Todo;
先前的类函数文件正在转换为上面的钩子文件:
import React from "react";
class Todo extends React.Component {
constructor(props) {
super(props);
this.state = { items: [], text: "" };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label htmlFor="new-todo">What needs to be done?</label>
<input
id="new-todo"
onChange={this.handleChange}
value={this.state.text}
/>
<button>Add #{this.state.items.length + 1}</button>
</form>
<TodoList items={this.state.items} />
</div>
);
}
handleChange(e) {
this.setState({ text: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
if (this.state.text.length === 0) {
return;
}
const newItem = {
text: this.state.text,
id: Date.now(),
};
this.setState((state) => ({
items: state.items.concat(newItem),
text: "",
}));
}
}
class TodoList extends React.Component {
render() {
return (
<ul>
{this.props.items.map((item) => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
}
export default Todo;
非常感谢!
3个回答
发生这种情况是因为在 handleChange 中你用 { text: e.target.value } 重写了整个状态(状态钩子的工作方式与基于类的组件状态不同) 你应该尝试这个:
const handleChange = (e) => {
setState((prevState) => {...prevState, text: e.target.value });
};
ComixRu
2022-08-01
如果我必须转换,那么我会以这种方式进行。
729339205
Najmus Sakib
2022-08-01
该问题很可能是由于此代码块造成的。
const handleChange = (e) => {
setState({ text: e.target.value });
// mutating state as this will overwite the current values with
// {text: e.target.value }
};
更好的方法可能是使用如下的其余语法。
const handleChange = (e) => {
setState((prev) => { return {...prev, [text]: e.target.value }});
// and now when you update text, it shouldnt overwrite your items or
//vice versa
};
Joseph Walker
2022-08-01