safe-wallet-web
safe-wallet-web copied to clipboard
refactor: usage of getTransactionDetails
Today with @usame-algan we found out that our use of useIntervalCounter was causing the txDetails component to also rerender every 15s despite no data changing. All this was introduced when we wanted to poll the getTransactionDetails for swap transactions (as they can change their status from open to fullfilled, canceled etc) It turned out to be very hard to rewrite our useAsync pattern to poll & I thought that this could be good exercise to test rtk query. I'm very pleased with the result.
This:
const [pollCount] = useIntervalCounter(POLLING_INTERVAL)
const swapPollCount = isOpenSwapOrder(txSummary.txInfo) ? pollCount : 0
const [txDetailsData, error, loading] = useAsync<TransactionDetails>(
async () => {
if (txDetails && swapPollCount <= 0) {
return txDetails
}
return getTransactionDetails(chainId, txSummary.id)
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[txDetails, chainId, txSummary.id, safe.txQueuedTag, swapPollCount],
false,
)
turned into this
const {
data: txDetailsData,
error,
isLoading: loading,
refetch,
} = useGetTransactionDetailsQuery(
{ chainId, txId: txSummary.id },
{
pollingInterval: isOpenSwapOrder(txSummary.txInfo) ? 2000 : undefined,
},
)
useEffect(() => {
refetch()
}, [safe.txQueuedTag, refetch, txDetails])
Notice that we are outsourcing the polling to rtk if we are dealing with a swap order. If not, we just fetch the information and keep it in the store. Any other component that needs the same data can access it and won't have to do a new ajax request for that.
The data is kept for as long as there is a component on the page using the data. If the user navigates away the data will be kept in the store for 60s and will be removed. The next time the user goes tries to view the data it will be refetched. All this is configurable.
I've changed few more places where we use getTransactionDetails. I also noticed that we use the getTxDetails function as a memoized version of getTransactionDetails in tracking or notification code. I'll try to think if we could be move this to also use rtk. It should be possible to use it without hooks, so this would be also cool.
What it solves
Fixes unnecessary rerenders, makes our code easier to read, reduces network requests.
Notice that I've opted for calling this reducer gatewayAPI. The idea is to add the getBalance, getChains calls in there.
How to test it
Run the site with redux devtools extension in your browser. You should see redux events being dispatched that fetch the data from the server and save it in the store.
Screenshots
Checklist
- [ ] I've tested the branch on mobile 📱
- [ ] I've documented how it affects the analytics (if at all) 📊
- [ ] I've written a unit/e2e test for it (if applicable) 🧑💻