Handling stale data & optimistic updates. #70
-
Hey! We added boxed wrappers to our graphql queries to reduce amount of states that we need to handle. const [queryState, refetch] = _useQuery({
query,
variables,
context: React.useMemo(() => context, contextDependencies),
pause,
});
let state: AsyncData<Result<Data, Error> = AsyncData.NotAsked();
if (queryState.data) {
state = AsyncData.Done(Result.Ok(queryState.data));
}
if (queryState.error) {
state = AsyncData.Done(Result.Error(queryState.error));
}
if (queryState.fetching) {
state = AsyncData.Loading();
}
return [state, refetch]; Unfortunately that made it hard for us to add optimistic updates. So instead we moved to const [queryState, refetch] = useQuery({
query,
variables,
context: React.useMemo(() => context, contextDependencies),
pause,
});
let state: AsyncData<UseQueryState<Data, Variables>> = AsyncData.NotAsked();
if (queryState.data) {
state = AsyncData.Done(queryState);
}
if (queryState.fetching) {
state = AsyncData.Loading();
}
return [state, refetch]; This however feels a bit like a step back - we are handling |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
hi! what exactly do you mean by optimistic updates? those should not trigger a loading state on a query. can you provide an example of the issue? |
Beta Was this translation helpful? Give feedback.
-
@bloodyowl hey, sure thing, let me describe the problem better. LMK if this makes more sense, maybe there's a pattern I don't know yet that would solve my issue. Let's say we create a way to read an async list of todos. let todos = AsyncData.Idle()
async function fetchTodos() {
todos = AsyncData.Loading()
response = await fetch(...)
todos = AsyncData.Done(response)
} Then let's say we want to be able to add the todo. let action = AsyncData.Idle()
async function removeTodo(id) {
action = AsyncData.Loading()
actionResult = await fetch(...)
action = AsyncData.Done(actionResult)
} We could then use
Both of these are not possible with a singular optimistic updates: let action = AsyncData.Idle()
async function removeTodo(id) {
action = AsyncData.Loading(id)
actionResult = await fetch(...)
action = AsyncData.Done(actionResult)
}
if (action.isLoading() && action.getLoading() == todo.id) {
// show action dots
} stale data refetches: async function fetchTodos() {
if (todos.isDone()) {
todos = AsyncData.Loading(todos.get())
} else {
todos = AsyncData.Loading()
}
response = await fetch(...)
todos = AsyncData.Done(response)
}
todos.match({
Loading: (stale) => // display stale UI,
}) |
Beta Was this translation helpful? Give feedback.
yeah, you can do something like this: