3.1Kпросмотров
76.0%от подписчиков
31 января 2025 г.
Score: 3.4K
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