React 中的搜索栏有效,但遇到非常奇怪的行为
Search bar in react works, but experiencing very strange behaviour
在提供输入的组件中,它会将输入分派给减速器
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value)
dispatch(userActions.searchByName(searchTerm));
}
然后 reducer 获取该值并尝试根据该输入过滤数组
searchByName: (state, action) => {
state.search = action.payload;
let newArray = state.users.filter((user) =>
user.name.toLowerCase().includes(state.search.toLowerCase())
);
state.users = newArray;
},
然后整个数组显示在其他组件之一中。搜索栏在某种程度上起作用:
当您开始在搜索栏中输入内容时,它只会在第二次输入后才开始工作。在控制台中,我注意到如果您键入“Timmothy”,它只会在该州注册“Timmothy”。
此外,如果我从输入中删除文本,即使输入值发生变化,数组的状态也不会更新并保持不变。
所以当前发生的情况是,如果您开始在搜索栏中键入内容,它会更新数组,但始终只记录倒数第二个击键。此外,如果您从搜索栏中删除输入,它不会注册。值发生变化,但数组保持不变,只剩下很少的项目。
我试过不使用附加变量来存储状态,而是这样做的
state.users.filter((user) =>
user.name.toLowerCase().includes(state.search.toLowerCase())
但之后绝对没有任何反应。如果有人能告诉我我在这里缺少什么,将不胜感激
编辑
这是接收该输入的组件
<input onChange={changeSearchTerm} type="text" value={searchTerm}></input>
并且 searchTerm
值保存在 useState - const [searchTerm, setSearchTerm] = useState("");
据我所知,由于这个块,它仅在第二次输入后有效:
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value)
dispatch(userActions.searchByName(searchTerm));
}
像 setSearchTerm
这样的状态设置器实际上是 asynchronous。这意味着在您调用 setSearchTerm
之后,在下一行中 searchTerm
的值仍然是旧值。
您可以改为执行以下操作之一:
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value)
dispatch(userActions.searchByName(e.target.value));
}
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value, () => {
// This callback runs only after state has changed
dispatch(userActions.searchByName(searchTerm));
});
}
编辑:抱歉,我错过了您使用的 useState/functional。您可以使用 useEffect
:
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value);
}
useEffect(() => {
if (searchTerm.length > 0) {
dispatch(userActions.searchByName(searchTerm));
}
}, [searchTerm]);
这样,只要 searchTerm 的值肯定发生变化,您的调度就会正确 运行。
在提供输入的组件中,它会将输入分派给减速器
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value)
dispatch(userActions.searchByName(searchTerm));
}
然后 reducer 获取该值并尝试根据该输入过滤数组
searchByName: (state, action) => {
state.search = action.payload;
let newArray = state.users.filter((user) =>
user.name.toLowerCase().includes(state.search.toLowerCase())
);
state.users = newArray;
},
然后整个数组显示在其他组件之一中。搜索栏在某种程度上起作用: 当您开始在搜索栏中输入内容时,它只会在第二次输入后才开始工作。在控制台中,我注意到如果您键入“Timmothy”,它只会在该州注册“Timmothy”。 此外,如果我从输入中删除文本,即使输入值发生变化,数组的状态也不会更新并保持不变。
所以当前发生的情况是,如果您开始在搜索栏中键入内容,它会更新数组,但始终只记录倒数第二个击键。此外,如果您从搜索栏中删除输入,它不会注册。值发生变化,但数组保持不变,只剩下很少的项目。
我试过不使用附加变量来存储状态,而是这样做的
state.users.filter((user) =>
user.name.toLowerCase().includes(state.search.toLowerCase())
但之后绝对没有任何反应。如果有人能告诉我我在这里缺少什么,将不胜感激
编辑
这是接收该输入的组件
<input onChange={changeSearchTerm} type="text" value={searchTerm}></input>
并且 searchTerm
值保存在 useState - const [searchTerm, setSearchTerm] = useState("");
据我所知,由于这个块,它仅在第二次输入后有效:
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value)
dispatch(userActions.searchByName(searchTerm));
}
像 setSearchTerm
这样的状态设置器实际上是 asynchronous。这意味着在您调用 setSearchTerm
之后,在下一行中 searchTerm
的值仍然是旧值。
您可以改为执行以下操作之一:
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value)
dispatch(userActions.searchByName(e.target.value));
}
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value, () => {
// This callback runs only after state has changed
dispatch(userActions.searchByName(searchTerm));
});
}
编辑:抱歉,我错过了您使用的 useState/functional。您可以使用 useEffect
:
const changeSearchTerm = (e) => {
setSearchTerm(e.target.value);
}
useEffect(() => {
if (searchTerm.length > 0) {
dispatch(userActions.searchByName(searchTerm));
}
}, [searchTerm]);
这样,只要 searchTerm 的值肯定发生变化,您的调度就会正确 运行。