javascript - 如果不单击多次,React 提交表单按钮将不起作用
问题描述
我正在开发我的第一个 React 程序,它是由 Sololearn(Contact Manager)提供的。我正在尝试添加一个功能来搜索联系人:SearchName。但是,我需要多次单击“搜索”按钮才能使其正常工作。有人可以告诉我哪里出错了吗?例如,首先在输入要搜索的名称字段中输入James Smith会给出“不在列表中”。然后再次单击时,它会更新为is in list。
这是代码:
import React, { useState } from "react";
import ReactDOM from "react-dom";
function AddPersonForm(props) {
const [person, setPerson] = useState("");
function handleChange(e) {
setPerson(e.target.value);
}
function handleSubmit(e) {
if (person !== "") {
props.handleSubmit(person);
setPerson("");
}
e.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Add new contact"
onChange={handleChange}
value={person}
/>
<button type="submit">Add</button>
</form>
);
}
function RemovePersonForm(props) {
const [person, setPerson] = useState("");
function handleChange(e) {
setPerson(e.target.value);
}
function handleSubmit(e) {
props.handleSubmit(person);
setPerson("");
e.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="enter name to delete"
onChange={handleChange}
/>
<button type="submit">Delete</button>
</form>
);
}
function PeopleList(props) {
const arr = props.data;
const listItems = arr.map((val, index) => <li key={index}>{val}</li>);
return <ul>{listItems}</ul>;
}
function SearchName(props) {
const [contacts, setContacts] = useState(props.data);
const [person, setPerson] = useState("");
const [isInList, setIsInList] = useState(false);
const [text, setText] = useState("");
function handleChange(e) {
setPerson(e.target.value);
}
function handleSubmit(e) {
setIsInList(false);
for (var c of contacts) {
if (c == person) {
setIsInList(true);
break;
}
}
if (isInList) {
setText("is in list");
} else {
setText("is not in list");
}
e.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="enter name to search"
onChange={handleChange}
/>
<button type="sumbit">Search</button>
<p>{text}</p>
</form>
);
}
function ContactManager(props) {
const [contacts, setContacts] = useState(props.data);
function addPerson(name) {
setContacts([...contacts, name]);
}
function removePerson(name) {
var newContacts = new Array();
var i = 0;
for (var c of contacts) {
if (c != name) {
newContacts[i] = c;
i++;
}
}
setContacts(newContacts);
}
return (
<div>
<AddPersonForm handleSubmit={addPerson} />
<RemovePersonForm handleSubmit={removePerson} />
<SearchName data={contacts} />
<PeopleList data={contacts} />
</div>
);
}
const contacts = ["James Smith", "Thomas Anderson", "Bruce Wayne"];
ReactDOM.render(
<ContactManager data={contacts} />,
document.getElementById("root"),
);
解决方案
根本问题是,由于setState
是异步的,isInList
所以在您签入时还没有时间更改handleSubmit
。
但是,由于 printtext
严格来说是是否isInList
为真的函数,因此它不应该是一个单独的状态原子。如果计算更复杂,我建议使用useMemo
它。
在类似的说明中,您不应该将data
道具“分叉”到本地联系人状态。
最后,您可以将查找过程简化为简单的.find
调用而不是循环。
function SearchName(props) {
const [person, setPerson] = useState("");
const [isInList, setIsInList] = useState(false);
function handleChange(e) {
setPerson(e.target.value);
}
function handleSubmit(e) {
setIsInList(props.data.find((c) => c === person));
e.preventDefault();
}
const text = isInList ? "is in list" : "is not in list";
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="enter name to search"
onChange={handleChange}
/>
<button type="sumbit">Search</button>
<p>{text}</p>
</form>
);
}
推荐阅读
- python - matplotlib:如何绘制曲面与 z 平面的 2D 相交曲线?
- python - python切片的奇怪行为
- python - OSError:没有可用的默认输入设备(PyAudio)
- javascript - 使用 Angular js(获取)从大型 API 动态呈现答案
- rest - Gin 错误恐慌:通配符路由与现有子节点冲突
- mongodb - Mongoose:用于级联删除的 deleteOne 中间件不起作用
- sql - SQLAlchemy/SQL:过滤表,然后加入查询
- ssh - SSH Windows 10,找出什么版本
- esb - Transformers 不能循环遍历列表元素
- multithreading - 不覆盖*标准输入*可防止多线程