redux-toolkit
redux-toolkit copied to clipboard
Feature request: pass `pollingInterval` a function
Use case:
- I have an API where I need to place an order with one endpoint and then poll for the order to get the payment status with another endpoint.
- Depending on the payment status, I move the customer on to a confirmation page or let them retry their payment details.
- I want to stop polling when the payment status is
FAILED
. Currently my component looks a bit like this
Here's a rough WIP of how I would see this looking in practice:
export const PaymentForm = (): ReactElement => {
const [shouldPoll, setShouldPoll] = useState(false);
const [createOrder, { data: createdOrder }] = useCreateOrderMutation();
const { data: orderStatus, isSuccess: hasOrderStatus } = useGetOrderStatusQuery(
createdOrder ? { orderNumber: createdOrder.orderNumber } : skipToken,
{ pollingInterval: shouldPoll ? 1000 : 0 }
);
if (shouldPoll && hasOrderStatus && orderStatus.paymentStatus === 'FAILED') {
setShouldPoll(false);
}
if (orderStatus.paymentStatus === 'SUCCESS') {
// navigate to confirmation page
}
const handleSubmit = () => {
createOrder()
.unwrap()
.then(() => {
setShouldPoll(true);
})
.catch(() => {
setShouldPoll(false);
});
};
return (
<div>
<form onSubmit={handleSubmit} />
{/* Something using orderStatus */}
</div>
);
};
I'd like to be able to eliminate the need for the shouldPoll
status, which I'm currently updating after unwrapping createOrder
and comparing/updating in render.
If pollingInterval
accepted a callback that received the current query data (and possibly other flags like isSuccess
) I could use the current state of the data to determine if the query should keep polling:
const { data: orderStatus, isSuccess: hasOrderStatus } = useGetOrderStatusQuery(
createdOrder ? { orderNumber: createdOrder.orderNumber } : skipToken,
{
pollingInterval: (data) => (data?.paymentStatus === 'FAILED' ? 0 : 1000),
}
);
With this in place, if a payment fails:
- a second submission of the form would trigger a new
createOrder
mutation - when this resolves with a new order number, a new query would be triggered
- when the data updates, the query would start polling again
I then no longer need local state or to unwrap my mutation result in handleSubmit
.
Tanstack Query has a similar API via refetchInterval
- https://tanstack.com/query/latest/docs/framework/react/reference/useQuery
The possible drawbacks I can see are:
- May not be clear how to restart polling after data has reached a certain state. You essentially need to call
refetch
, and hope the data has changed, or change the query args - If including flags like
isSuccess
,isFetching
etc., it may not be clear ifpollingInterval
is only evaluated whendata
changes, or when the flags themselves change.
I think this could be done without a breaking change given the option currently only accepts a number.