Методология: Реализация логики для действий пользователя? (Без дублирования кода между клиентом и сервером или неприемлемого UX)

Давайте придумаем игрушечный случай: предположим, у нас есть приложение, в котором есть кнопка «большой палец вверх» для каждого сообщения — вы знаете, при нажатии на нее кнопка должна стать синей, и сервер должен запомнить, что этот парень поднял ее.

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


К вашему сведению, вот мои две попытки:

Метод A. При нажатии активируются две функции. (1) Непосредственно измените состояние (например, в Redux), установив state.thumbup=true, а затем React автоматически повторно отобразит пользовательский интерфейс. В то же время (2) отправьте сообщение HTTP на сервер. Когда сервер получит его, он обновит свою базу данных (например, user.setThumbUp(true);repo.save(user);).

Проблема в том, что мне приходится дублировать свою логику дважды, один раз на клиенте ("при нажатии state.thumbup становится 1") и один раз на сервере ("если щелкает клиент, одно место в база данных изменится на 1"). В нашем примере это просто, но это не соответствует правилу KISS, и много кода дублируется, когда действие усложняется...

Метод B: при нажатии клиент не изменяет никакого локального состояния. Вместо этого мы отправляем только сообщение HTTP на сервер. Затем сервер получает его и изменяет свою базу данных. После того, как мы знаем, что сервер выполнил свою работу, клиент запускает HTTP-запрос, чтобы получить последнее состояние всей страницы. После того, как клиент получает данные, они отображаются, и пользователь видит, что палец вверх окрашивается.

Конечно, при этом исчезает дублирование кода. Однако теперь пользователь будет долго ждать (ожидая HTTP-запроса), прежде чем увидит, что пользовательский интерфейс изменился. Кажется, это тоже очень плохо...

Поэтому мне интересно, есть ли лучшее решение? Или все просто используют первый метод? Большое спасибо!


person ch271828n    schedule 16.01.2020    source источник
comment
Взгляните на stackoverflow.com/questions/33009657/, это не то же самое, но это даст вам некоторое представление о том, что вы пытаетесь решить.   -  person Johan    schedule 16.01.2020
comment
@Johan Большое спасибо за предоставление этого термина и подсказки! Итак, большинство приложений используют эту методологию оптимистичных обновлений? И как они удаляют дублирование кода?   -  person ch271828n    schedule 16.01.2020
comment
Как указано в комментариях, SO использует этот шаблон (и многие другие, например, FB, но с дополнительной функцией поддержки в автономном режиме). К сожалению, логику придется дублировать. Это цена, которую мы платим за лучший UX.   -  person Johan    schedule 16.01.2020
comment
@Johan О, так грустно дублировать это :( Большое спасибо!   -  person ch271828n    schedule 16.01.2020
comment
Просто помните, что вам нужно обрабатывать сбои сети, разрешение конфликтов и т. д., т.е. если запрос не выполнен, вам нужно откатить локальное состояние.   -  person Johan    schedule 16.01.2020
comment
@Johan Йохан А, это правда, так что есть еще много вещей, которые нужно учитывать ... Итак, есть ли у нас какие-либо фреймворки, которые могут обрабатывать это автоматически?   -  person ch271828n    schedule 16.01.2020
comment
Быстрый поиск в Google предлагает github.com/ForbesLindesay/redux-optimist, но я не использовал это я сам.   -  person Johan    schedule 16.01.2020
comment
@Johan Большое спасибо! Я попробую это или поищу еще!   -  person ch271828n    schedule 16.01.2020


Ответы (1)


Метод А лучше. Чтобы решить ваши проблемы:

  1. Дублирование логики: вам нужно будет только, так сказать, дублировать «операцию записи». Редуктор сохранит состояние «большой палец вверх», а создатель действия отправит запрос API, чтобы сделать «большой палец вверх» на сервере. Но основная проводка кнопки -> действие «большой палец вверх» остается прежним. Компонент React не знает об оптимистичных обновлениях и просто рендерит свои реквизиты. Так что это не дублирование логики как таковой, вы просто добавляете больше логики для улучшения UX, что является законным.

  2. Откат/обработка ошибок: Метод А и Б можно комбинировать. Вы бы отправили запрос API для одобрения, дождались его успеха или неудачи и, наконец, отправили запрос GET, который извлекает тот же ресурс, который вы пытались изменить на сервере (поскольку это источник правды). Это откатывает оптимистическое обновление, если операция записи не удалась. Или просто ничего не делает в случае успеха, но гарантирует, что у вас в магазине есть актуальный ресурс.

Тем не менее, я предполагаю, что 80% приложений React/Redux не делают оптимистичных обновлений, поскольку большинство разработчиков тестируют быстрые интернет-соединения и просто не знают о плохом UX с медленными соединениями. Но это правильно.

person timotgl    schedule 16.01.2020