试图在筛选之前重置列表,但在异步状态方面遇到问题



所以我有一个带有对象数组的常量,名为"数据";,接收数据的状态,这样我可以在更改屏幕时更新屏幕,并且我有一个过滤数据的功能。

每次用户更改HTML select的状态时,我都会触发一个名为handleChange的函数来调用filter函数,这样用户就可以看到过滤后的内容。问题是,我想在过滤数据之前用原始数据重置接收数据的状态,所以如果用户更改了其中一个选择,它会根据原始数据进行过滤,而不是以前更改的数据,但当我尝试用常量数据值更新状态时,它不起作用。

这是我的代码

const [list, setList] = useState<IData[]>([...data]);
const [filter, setFilter] = useState<IFilter>({
name: "",
color: "",
date: "",
});
function handleChange(
key: keyof IData,
event: React.ChangeEvent<{ value: string }>
): void {
const newFilter = { ...filter };
newFilter[key as keyof IData] = event.target.value;
setList([...data]); // reset the data
setFilter({ ...newFilter }); // set the filter value
filterList();
}

function filterList(): void {
const keys = Object.keys(filter) as Array<keyof IData>;
keys.forEach((key: keyof IData) => {
if (filter[key]) {
const newList = list.filter((item: IData) => item[key] === filter[key]);
setList([...newList]);
}
});
}

问题出在这里

setList([...data]); // reset the data
setFilter({ ...newFilter }); // set the filter value
filterList();

显然,当filterList发生时,列表状态还没有用数据值重新启动,因为如果我控制台将其记录在filterList((中,它只会返回以前筛选过的列表。有没有办法确保setList在筛选之前发生,这样我就可以确保筛选的列表总是基于初始值?

您可以访问useEffect内部的更新值(更多关于useEffect的信息(,因此您不需要直接在处理程序内部调用filterList(),而是将其移动到钩子内部:

React.useEffect(()=>{filterList();},[list,filter])

或者,在用更新状态后,您可以将值作为参数传递给函数

filterList(newList, newFilter)

更新当您在filterList中更新list时,您将需要某种标志来指示是否需要过滤(我会使用useRef(。请注意,最好将参数传递到filterList中,因为这样会减少一个渲染周期。以下是两者如何工作的简化示例,如果它们有意义,请告诉我:https://jsfiddle.net/6xoeqkr3/

最新更新