我只是想找出一个奇怪的问题在我的React项目。我在我的useEffect中执行一些代码。正如您所看到的,我正在尝试从基于searchTerm的对象数组中获取currentObj。然而,在获取值searchTerm时似乎存在竞争条件。下面的toggleFilter和setavailability函数抛出一个错误,说id没有定义。页面崩溃
useEffect(() => {
const search = window.location.search;
const params = new URLSearchParams(search);
let param = "";
if (search.includes("neighborhood")) {
param = params.get("neighborhood");
const searchTerm = search.toLowerCase();
if (searchTerm) {
const currentObj = searchTerm && locations.find(item => item.linktitle.toLowerCase().includes(searchTerm));
console.log(searchTerm, currentObj);
toggleFilter(currentObj.id);
setAvailabilitiesFilter([currentObj.id]);
}
}
return () => resetAllFilters();
}, []);
然而,如果我硬编码一个值到它,它实际上呈现正常,页面不会崩溃。
const currentObj = searchTerm && locations.find(item => item.linktitle.toLowerCase().includes('manhattan'));
这就是为什么我认为这是一个竞争条件在获得id。另外,当我查看来自硬编码searchTerm的控制台日志时,它显示了searchTerm属性。但是我不想硬编码它。
当然,我不想硬编码这个值因为我希望动态呈现searchTerm
是否有任何方法我可以在useEffect等待直到searchTerm被定义之前运行。find方法?我还尝试在依赖数组中添加searchTerm,但这似乎不正确,因为它没有给出建议,似乎不在那里。
感谢任何帮助。谢谢!
你试过吗?
const search = window.location.search;
search.substring(1) // this will ignore "?" in the result which could be causing the issue on finding the correct object
您是否尝试在这里打印search的值?
console.log(search);
如果是,你看到的是什么?
同样,你不需要重复自己这样做:
if (searchTerm) {
const currentObj = searchTerm && locations.find(item => item.linktitle.toLowerCase().includes(searchTerm));
...
}
你已经检查了searchTerm是否已经在if语句中定义了,所以你可以简单地这样做:
if (searchTerm) {
const currentObj = locations.find(item => item.linktitle.toLowerCase().includes(searchTerm));
...
最后,为了避免任何其他错误,在使用你的函数之前,你可以检查你是否真的有一个id,像这样:
if(currentObj.id) {
toggleFilter(currentObj.id);
setAvailabilitiesFilter([currentObj.id]);
}
希望有帮助!
问题似乎是您在.find
谓词回调中使用整个查询搜索字符串。
useEffect(() => {
const search = window.location.search; // <-- entire search string
const params = new URLSearchParams(search);
let param = "";
if (search.includes("neighborhood")) {
param = params.get("neighborhood");
const searchTerm = search.toLowerCase(); // <-- still entire search string
if (searchTerm) {
const currentObj = searchTerm && locations.find(
item => item.linktitle.toLowerCase()
.includes(searchTerm) // <-- still entire search string
);
console.log(searchTerm, currentObj);
toggleFilter(currentObj.id); // <-- throws error if undefined currentObj
setAvailabilitiesFilter([currentObj.id]);
}
}
return () => resetAllFilters();
}, []);
Array.prototype.find
返回undefined,当使用谓词函数没有找到数组元素,并且代码在试图访问嵌套属性(如id
)之前没有正确检查结果值是否为真。
我现在猜测您想要搜索链接标题以寻找匹配的邻域值,即代码中的param
。
useEffect(() => {
const search = window.location.search;
const params = new URLSearchParams(search);
// get the neighborhood querystring param
const neighborhood = params.get("neighborhood");
// check if it exists
if (neighborhood) {
// it does, search the locations array
const currentObj = locations.find(
({ linktitle }) => linktitle.toLowerCase().includes(neighborhood.toLowerCase())
);
// check if result was found
if (currentObj) {
// it was found, access into object to get id property
toggleFilter(currentObj.id);
setAvailabilitiesFilter([currentObj.id]);
}
}
return () => resetAllFilters();
}, []);