joinmarket-webui / joinmarket-webui/jam

refactor: let react-query handle displaywallet UTXO changes

Open
#1,464 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
330
Forks
122
Avg merge
2d 17h
Merged PRs (30d)
17

Description

# Refactor: Let React Query Handle `displaywallet` UTXO Changes

## Summary

Follow-up to #1448.

While working on #1448, we fixed the unnecessary initial wallet refetch caused by the `AFTER_UTXO_CHANGE` effect.

During the review, we discussed that instead of guarding this effect, a cleaner approach is to let React Query handle the dependency directly through the `displaywallet` query key.

This PR implements that follow-up approach.

---

## Problem

`useQueryDisplayWallet` already receives `utxosHashHex`, but it is currently passed through:

```ts
meta.cacheBuster
```

However, `meta` is not part of the generated `createQueryKey`.

The generated query key only considers values such as:

```text
_id
baseUrl
body
headers
path
query
```

As a result, changing `utxosHashHex` does not change the identity of the `displaywallet` query.

To keep the wallet information synchronized with UTXO changes, the application currently relies on the manual `AFTER_UTXO_CHANGE` effect.

### Current flow

```text
UTXO state changes

utxosHashHex changes

AFTER_UTXO_CHANGE effect

refetchWalletBalance()

/utxos + /displaywallet

wallet state refreshed
```

This introduces a separate synchronization layer even though `displaywallet` is already managed by React Query.

---

## Approach

Make the UTXO state part of the `displaywallet` query identity.

When `utxosHashHex` changes:

```text
utxosHashHex changes

displaywallet query key changes

React Query detects a new query key

displaywallet refetches automatically
```

Conceptually, the dependency becomes part of the query itself:

```ts
queryKey: [
// existing displaywallet query identity
utxosHashHex,
]
```

instead of relying on:

```text
utxosHashHex

useEffect

AFTER_UTXO_CHANGE

manual refetch
```

---

## Before

```text
utxosHashHex


WalletInfoAutoReload


AFTER_UTXO_CHANGE


refetchWalletBalance()
│ │
▼ ▼
/utxos /displaywallet
```

## After

```text
utxosHashHex


displaywallet query key


React Query


/displaywallet
```

---

## Changes

- Make `utxosHashHex` part of the `displaywallet` query identity
- Let React Query handle `displaywallet` refetches when the UTXO state changes
- Remove the now-unnecessary manual `AFTER_UTXO_CHANGE` refetch path
- Simplify the wallet auto-reload flow
- Update the related tests for the query-key based behavior

---

## Why This Is Better

The previous implementation manually synchronized two pieces of state:

```text
UTXO state

effect

wallet state
```

With the query-key approach, the dependency is expressed directly where the data is fetched:

```text
UTXO state

query identity

React Query

wallet state
```

This removes the need for a separate effect whose only responsibility is triggering another refetch.

It also makes React Query responsible for the cache/refetch behavior instead of duplicating that responsibility inside `WalletInfoAutoReload`.

---

## Relation to #1448

#1448 addressed the immediate issue by preventing the initial `AFTER_UTXO_CHANGE` execution from causing an unnecessary wallet refetch.

```text
#1448


Guard unnecessary initial refetch
```

During its review, we identified a cleaner follow-up:

```text
#1448


Guard AFTER_UTXO_CHANGE


This PR


Move UTXO dependency into query key


Let React Query handle the refetch


Remove manual AFTER_UTXO_CHANGE path
```

This PR implements that follow-up and simplifies the underlying approach rather than adding another guard around the existing effect.

---

## Testing

The related tests cover the new query-key based behavior and verify that:

- `displaywallet` continues to load normally
- UTXO state changes update `utxosHashHex`
- A changed `utxosHashHex` changes the relevant query identity
- React Query performs the expected `displaywallet` refetch
- The manual `AFTER_UTXO_CHANGE` refetch path is no longer required
- Existing wallet refresh behavior remains intact

---

## Result

The wallet refresh flow moves from:

```text
UTXO change
→ detect change manually
→ run effect
→ manually refetch wallet
```

to:

```text
UTXO change
→ query key changes
→ React Query handles refetch
```

This keeps the UTXO → `displaywallet` dependency in the query layer and simplifies the wallet auto-reload logic.

This is the follow-up approach discussed during the review of #1448.

Contributor guide

Open the contributing guide

Research direction

Start with useQueryDisplayWallet and WalletInfoAutoReload, then inspect the related tests for the displaywallet query and AFTER_UTXO_CHANGE flow. Trace how utxosHashHex currently reaches meta.cacheBuster and how the generated query key is built. Done means UTXO changes update the query identity, the expected displaywallet refetch occurs, and the manual refetch path is no longer required.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.