使用 lodash debounce 时 React 挂钩状态出现问题
Issue with React hook state while working with lodash debounce
我不太确定到底是什么导致了这个问题。所以我有一个组件可以根据某些动作显示图片的数量。我有一个滑块和一个下拉组件来模拟操作。
我在滑块上使用 lodash 去抖动。所以确切的问题是我有一个状态来跟踪过滤器的初始值,比如带有 dog
的类别
const initialValue = {
filters: [
{
field: "category",
values: ["dog"]
}
]
}
const [myFilter, setMyFilter] = useState(initialValue)
有了上面的初始值,组件会抓取所有类别为狗的图片并显示在页面上。然后我可以添加一个下拉值来过滤掉图像大小,所以我的状态输出如下:
myFilter = {
filters: [
{
field: "category",
values: ["dog"]
},
{
field: "size",
values: ["500x500"]
}
]
}
此时我的最新状态应该如上。我为时间范围添加了一个 debounce
以便函数如下所示
onTimeRangeChange = (value) => {
// update range state
setRange(value);
}
const handleSetTimeRange = (value: number[]) => {
const merge = {
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
},
};
console.log("myFilter: ", myFilter);
setMyFilter({ ...myFilter, time_range: merge });
};
const handleDebounce = useCallback(debounce(handleSetTimeRange, 500), [])
useEffect(() => {
if(prevRange && oneRange !== prevRange)
{
handleDebounce(range)
}
}, [range])
所以myFilter
毕竟预计是
myFilter = {
filters: [
{
field: "category",
values: ["dog"]
},
{
field: "size",
values: ["500x500"]
}
],
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
}
}
但实际值如下所示:
myFilter = {
filters: [
{
field: "category",
values: ["dog"]
}
],
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
}
}
它以某种方式删除了过滤器下的尺寸对象。我不确定实际发生了什么,我对 debounce 和 useCallback 不是很熟悉。他们会重置状态吗?
看起来 useCallback
挂钩有一个空的依赖数组,
const handleDebounce = useCallback(debounce(handleSetTimeRange, 500), []);
因此初始 myFilter
状态值在回调范围内关闭并且从未更新。
const handleSetTimeRange = (value: number[]) => {
const merge = {
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
},
};
console.log("myFilter: ", myFilter);
setMyFilter({ ...myFilter, time_range: merge });
};
您可能可以将 myFilter
添加到 useCallback
挂钩的依赖项数组以将更新后的 myFilter
状态值重新包含在回调范围中:
const handleDebounce = useCallback(
debounce(handleSetTimeRange, 500),
[myFilter],
);
或使用功能状态更新从任何先前状态正确更新:
const handleSetTimeRange = (value: number[]) => {
const merge = {
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
},
};
setMyFilter(myFilter => {
return {
...myFilter,
time_range: merge
}
});
};
我不太确定到底是什么导致了这个问题。所以我有一个组件可以根据某些动作显示图片的数量。我有一个滑块和一个下拉组件来模拟操作。
我在滑块上使用 lodash 去抖动。所以确切的问题是我有一个状态来跟踪过滤器的初始值,比如带有 dog
的类别const initialValue = {
filters: [
{
field: "category",
values: ["dog"]
}
]
}
const [myFilter, setMyFilter] = useState(initialValue)
有了上面的初始值,组件会抓取所有类别为狗的图片并显示在页面上。然后我可以添加一个下拉值来过滤掉图像大小,所以我的状态输出如下:
myFilter = {
filters: [
{
field: "category",
values: ["dog"]
},
{
field: "size",
values: ["500x500"]
}
]
}
此时我的最新状态应该如上。我为时间范围添加了一个 debounce
以便函数如下所示
onTimeRangeChange = (value) => {
// update range state
setRange(value);
}
const handleSetTimeRange = (value: number[]) => {
const merge = {
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
},
};
console.log("myFilter: ", myFilter);
setMyFilter({ ...myFilter, time_range: merge });
};
const handleDebounce = useCallback(debounce(handleSetTimeRange, 500), [])
useEffect(() => {
if(prevRange && oneRange !== prevRange)
{
handleDebounce(range)
}
}, [range])
所以myFilter
毕竟预计是
myFilter = {
filters: [
{
field: "category",
values: ["dog"]
},
{
field: "size",
values: ["500x500"]
}
],
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
}
}
但实际值如下所示:
myFilter = {
filters: [
{
field: "category",
values: ["dog"]
}
],
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
}
}
它以某种方式删除了过滤器下的尺寸对象。我不确定实际发生了什么,我对 debounce 和 useCallback 不是很熟悉。他们会重置状态吗?
看起来 useCallback
挂钩有一个空的依赖数组,
const handleDebounce = useCallback(debounce(handleSetTimeRange, 500), []);
因此初始 myFilter
状态值在回调范围内关闭并且从未更新。
const handleSetTimeRange = (value: number[]) => {
const merge = {
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
},
};
console.log("myFilter: ", myFilter);
setMyFilter({ ...myFilter, time_range: merge });
};
您可能可以将 myFilter
添加到 useCallback
挂钩的依赖项数组以将更新后的 myFilter
状态值重新包含在回调范围中:
const handleDebounce = useCallback(
debounce(handleSetTimeRange, 500),
[myFilter],
);
或使用功能状态更新从任何先前状态正确更新:
const handleSetTimeRange = (value: number[]) => {
const merge = {
time_range: {
start_time: moment(startTime + value[0] * 1000).toISOString(),
end_time: moment(startTime + value[1] * 1000).toISOString(),
},
};
setMyFilter(myFilter => {
return {
...myFilter,
time_range: merge
}
});
};