提问人:Worker1432 提问时间:11/10/2023 更新时间:11/10/2023 访问量:16
为什么在 React App 输入字段中键入 ANYTHING 会使我的 Persons 在基本的电话簿应用程序中显示为空白?
Why does typing ANYTHING in the React App input field make my Persons display blank for a rudimentary Phonebook App?
问:
我想做的是在我基本的 React 电话簿应用程序中创建一个搜索功能。人员的初始数据存储在项目根目录的 db.json 文件中。
这是一个有问题的代码,当我在输入字段中输入某些内容后,人员列表的整个显示都变为空白:
import React, {useState} from 'react';
const Search = ({persons, setPersons}) => {
const [filter, setFilter] = useState('');
const handleFilterEntry = (event) => {
const value = event.target.value;
setFilter(value);
const filteredPersons = persons.filter( person => {
person.name.toLowerCase().includes(value.toLowerCase())
});
setPersons(filteredPersons);
console.log(value);
}
return (
<div>
Filter names with: <input value = {filter} onChange={handleFilterEntry}/>
</div>
)
}
export default Search;
这是修复该问题的handleFilterEntry函数的更新代码:
const handleFilterEntry = (event) => {
const value = event.target.value;
setFilter(value);
const filteredPersons = value
? persons.filter(
(person) =>
person.name.toLowerCase().includes(value.toLowerCase())
)
: persons;
setPersons(filteredPersons);
console.log(value);
};
我想知道为什么添加条件逻辑有效并解决了问题?
我还想知道,在输入字段中向后退行某些字符时,为什么列表没有恢复为显示带有退格字母的人员列表。
示例:
列表中有 Joe 和 Jack 的名字。
我输入 J,它过滤到 Joe 和 Jack。
我输入 Jo,它过滤到 Joe。 但是我退格到只有 J,它不会恢复为在列表中同时显示 Joe 和 Jack,仍然只显示 Joe。
任何帮助将不胜感激,我是新手。提前致谢!
答:
第 1 部分。为什么它显示一个空列表
您没有在 filter 函数中返回检查值
person.name.toLowerCase().includes(value.toLowerCase())
应返回此值以使过滤器正常工作
第 2 部分。为什么退格不起作用?
现在,最初您的列表是
[jim, joe]
在搜索它变成
jo
[joe]
当您按退格键时,数组仍然是
[joe]
您已从该数组中删除,因此当您按退格键时,它不会出现在列表中
jim
我想知道为什么添加条件逻辑有效并解决了问题?
修复它的不是条件逻辑,而是你的过滤器函数现在返回一个值。你从这个开始:
persons.filter(person => {
person.name.toLowerCase().includes(value.toLowerCase())
});
上面的函数有大括号标记出函数体,但它没有语句。然后,您切换到以下位置:return
persons.filter((person) =>
person.name.toLowerCase().includes(value.toLowerCase())
)
大括号现在不见了。这意味着您使用的是箭头函数的简写版本。在速记语法中,javascript 会自动假定 .return
但是我退格到只有 J,它不会恢复为在列表中同时显示 Joe 和 Jack,并且仍然只显示 Joe。
那是因为您删除了该数据。每次键入字母时,都会收缩数组并设置状态。 永远不会增加数组的大小,所以当你删除一个字母时,它只会保持数组的大小与它已经相同的大小。.filter
解决方法是不改变;让它包含完整的数据集。然后,您将在渲染期间根据该列表计算过滤后的列表:persons
const Search = ({ persons, setPersons }) => {
const [filter, setFilter] = useState("");
const filteredPersons = persons.filter((person) =>
person.name.toLowerCase().includes(filter.toLowerCase()),
);
const handleFilterEntry = (event) => {
const value = event.target.value;
setFilter(value);
};
return (
<div>
Filter names with: <input value={filter} onChange={handleFilterEntry} />
</div>
);
};
您可以使用 useMemo 提高其性能,以便仅在相关内容发生更改时重新计算:filteredPersons
const filteredPersons = useMemo(() => {
return persons.filter((person) =>
person.name.toLowerCase().includes(filter.toLowerCase()),
);
}, [persons, filter]);
评论