React 上下文在超时中不是最新的
React context not being up to date in a Timeout
我正在使用 React 应用程序上下文来存储一组“警报对象”,这基本上是可能发生的任何错误,我想在网站的右上角显示。我遇到的问题是上下文在超时内没有更新。我为测试所做的是获得一个按钮,在单击时将警报对象添加到上下文,另一个组件映射到上下文中的该数组并呈现它们。我希望它们在 5 秒后消失,所以我添加了一个超时来过滤刚刚添加的项目并将其删除。问题是在超时内 context.alerts 数组似乎与 5 秒前具有相同的值,而不是使用导致问题和元素未被过滤掉的最新值。我不确定我的逻辑是否有问题,或者我是否使用了错误的上下文?
onClick={() => {
const errorPopup = getPopup(); // Get's the alert object I need
context.setAlerts([errorPopup, ...context.alerts]);
setTimeout(() => {
context.setAlerts([
...context.alerts.filter(
(element) => element.id !== errorPopup.id,
),
]);
}, 5000);
}}
我认为解决方法是将 context.setAlerts(...) 移动到一个单独的函数(比如 removePopupFromContext(id:string)),然后通过传递 errorPopup.Id作为参数。
我不确定你对 context.setAlerts 的实现,但如果它仅基于 setState 函数,那么你也可以做一些类似于 React 让你使用函数访问 setState 中的 prevState 的事情这将使您跳过额外功能的创建,该功能可能会轻微转化为:
setContext(prevContextState =>({
...prevContextState,
alerts: prevContextState.alerts.filter(your condition)
)})
onClick={() => {
const errorPopup = getPopup(); // Get's the alert object I need
context.setAlerts([errorPopup, ...context.alerts]);
setTimeout(() => {
context.setAlerts(alerts => [
...alerts.filter(
(element) => element.id !== errorPopup.id,
),
]);
}, 5000);
}}
这应该可以解决问题。在 react@17 之前,事件处理程序中的 setStates
被批处理(在 react@18 中,所有 setStates
甚至是异步的都被批处理),因此您需要使用最新的状态在第二个进行更新setAlerts
.
为了安全起见,最好在第一个 setState 中使用 cb
语法。
我正在使用 React 应用程序上下文来存储一组“警报对象”,这基本上是可能发生的任何错误,我想在网站的右上角显示。我遇到的问题是上下文在超时内没有更新。我为测试所做的是获得一个按钮,在单击时将警报对象添加到上下文,另一个组件映射到上下文中的该数组并呈现它们。我希望它们在 5 秒后消失,所以我添加了一个超时来过滤刚刚添加的项目并将其删除。问题是在超时内 context.alerts 数组似乎与 5 秒前具有相同的值,而不是使用导致问题和元素未被过滤掉的最新值。我不确定我的逻辑是否有问题,或者我是否使用了错误的上下文?
onClick={() => {
const errorPopup = getPopup(); // Get's the alert object I need
context.setAlerts([errorPopup, ...context.alerts]);
setTimeout(() => {
context.setAlerts([
...context.alerts.filter(
(element) => element.id !== errorPopup.id,
),
]);
}, 5000);
}}
我认为解决方法是将 context.setAlerts(...) 移动到一个单独的函数(比如 removePopupFromContext(id:string)),然后通过传递 errorPopup.Id作为参数。
我不确定你对 context.setAlerts 的实现,但如果它仅基于 setState 函数,那么你也可以做一些类似于 React 让你使用函数访问 setState 中的 prevState 的事情这将使您跳过额外功能的创建,该功能可能会轻微转化为:
setContext(prevContextState =>({
...prevContextState,
alerts: prevContextState.alerts.filter(your condition)
)})
onClick={() => {
const errorPopup = getPopup(); // Get's the alert object I need
context.setAlerts([errorPopup, ...context.alerts]);
setTimeout(() => {
context.setAlerts(alerts => [
...alerts.filter(
(element) => element.id !== errorPopup.id,
),
]);
}, 5000);
}}
这应该可以解决问题。在 react@17 之前,事件处理程序中的 setStates
被批处理(在 react@18 中,所有 setStates
甚至是异步的都被批处理),因此您需要使用最新的状态在第二个进行更新setAlerts
.
为了安全起见,最好在第一个 setState 中使用 cb
语法。