TGViewer
Заметки про React Заметки про React @ru_react_notes · 3.44K subscribers
Post #516 3.14K
UX++ и DX++ с движками синхронизации

В своем блоге Карл Ассманн объясняет почему сложно инвалидировать запросы и реализовать оптимистичный UI с React Query.

Сложность в инвалидации запросов заключается в том, что надо знать какие запросы нужно инвалидировать и когда. Если инвалидировать лишние ключи, то будут выполняться лишние запросы в сети. Также нужно знать все ключи, которые надо инвалидировать, иначе часть UI будет продолжать показывать устаревшие данные.

Для эффективной реализации оптимистичного UI нужно знать все связанные ключи запроса и влияние каждой мутации на них. Пример реализации оптимистичного UI:


const mutation = useMutation(addTodo, {
onMutate: async (newTodo) => {
const previousTodos = queryClient.getQueryData(...);
queryClient.setQueryData([newTodo, ...previousTodos]);
return { previousTodos };
},
onError: (_, _, context) => {
queryClient.setQueryData(["todos"], context.previousTodos);
},
onSettled: () => {
queryClient.invalidateQueries(["todos"]);
},
});


В оптимистичном UI также возникают сложности при добавлении нового запроса. Нужно связать существующие мутации, убедиться, что они инвалидируют этот запрос или вставляют правильные данные для оптимистичного UI.

По мнению автора, основная проблема клиентских приложений в том, что они работают с состоянием на сервере. Бывает нужно выполнить слишком много запросов, из-за которых пользователям приходится ждать, прежде чем они смогут продолжить.

В качестве решения проблемы автор предлагает обратить внимание на движки синхронизации, например Replicache.
Основная идея заключается в том, чтобы иметь локальную копию данных на клиенте. Компоненты подписываются на локальные данные или изменяют их, в то время как движок синхронизирует изменения с сервером в фоновом режиме.

Replicache работает только на клиенте, предоставляет методы подписки и мутации и взаимодействует с конечными точками API, позволяя вам контролировать ваш сервер, вашу базу данных и вашу бизнес-логику.

Пример подписки:


function Todos() {
const todos = useSubscribe(rep, async (tx) => {
return await tx.scan({prefix: "todo/"}).toArray();
});
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>✅ {todo.title}</li>
))}
</ul>
);
}


https://www.carlassmann.com/blog/improve-ux-dx-with-sync-engines
Carlassmann UX++ and DX++ with Sync Engines I share what I learn, do and think
  • 👍 14
More from @ru_react_notes
  1. Jun 24, 2025Реактивность – это легко Стандартный useContext заставляет обновляться все компоненты-потр…
  2. Jun 17, 2025Остерегайтесь скрытых проблем при работе с search params Типо-безопасность — это только ве…
  3. Jun 4, 2025Почему Error Boundary, а не просто try/catch для компонентов В React нельзя использовать t…
  4. May 29, 2025Анонс TypeScript Native Вышла превью версия TypeScript написанная на Go. Ее можно установи…
  5. May 27, 2025Управление фокусом в React с помощью flushSync Установить фокус на инпуте сразу в React мо…
  6. May 15, 2025TanStack DB TanStack представила новую библиотеку – TanStack DB – реактивный клиентский ст…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →