Верный способ инвалидации данных в redux store при работе с API?
Здравствуйте!
Часто при работе с redux и api возникает проблема, в store хранятся неактуальные для текущего момента данные.
Приведу абстрактный пример:
Есть форма комментариев. При отправке комментария, выполняется POST запрос на сервер, сервер может вернуть разные ответы, 200, 401, 403, 422, 500. В зависимости от ответа сервера срабатывает определенный Failure Action и в store попадет какая-то ошибка. Компонент, который присоединён к store, получает props и выводит ошибку на страницу. Далее, пользователь путешествует по сайту (SPA) и возвращается на страницу с комментариями, где благополучно снова выводится наша ошибка, хотя по идее, ошибка относится к предыдущему запросу.
Я вижу несколько решений, но нет уверенности, что они хорошие:
1. При размонтировании компонента (уход со страницы) сбрасывать state запроса. Получается, для каждого запроса у нас есть Action, который вернет состояние в первоначальное. Если на странице таких запросов много, появляется шанс где-то что-то забыть. На мой взгляд, решение не самое удачное.
2. Добавлять какой-то уникальный идентификатор или timestamp в Failure Action или Succes Action и в компоненте делать сравнение. Если это timestamp, то сравнение с текущим времени плюс какое-то значение погрешности. Это вариант кажется лучше, но смущает, что появляется какая-то неопределенная величина.
Я допускаю, что я, возможно, делаю что-то не так, совершаю ошибку при проектировании или реализации, но хочется разобраться и понять как правильно.
Коллеги, как вы решаете эту проблему?
Первым делом стоит уяснить что логика должна быть распределенна по отдельным функциям\экшенам. Вторым делом необходимо запомнить что компоненты должны быть максимально простые. Они должны выполнять роль посредника между логикой приложения и шаблоном. Отсюда следует что обязанность компонента page заключается лишь в уведомлении приложения о изменении состояния непосредственно страницы (зашли\вышли\может_что-то_ещё_наподобие_прокидования_данных_конкретного_роута). Когнетивной нагрузки совсем мало.
Но современные приложения зачастую очень сложные и требуют множества логики, речь о которой шла в "вопервых" и которая и должна быть сосредоточена в экшенах (зашел\вышел). То есть экшены должны представлять из себя древовидную структуру вызовов.
Ситуация с сообщением об ошибки которую вы обозначили как проблему вполне нормальная для spa + single app state. Вот если бы у вас была событийная модель, то вы бы с подобным не столкнулись, но точно также пришлось городить несуразицу если бы потребовалось сохранить последнее состояние. Поэтому пока при построении приложения используется только один архитектурный подход подобное не избежно.
Решение вы озвучили - необходимо завести экшены сбрасывающие состояние ошибок. Все остальные решения будут лишь излишними абстракциями над этим.
Небольшой хак — прятать подобные сообщения по таймауту.
Второй небольшой хак — использовать один компонент для вывода уведомлений на всех экранах. Проинициализировали алерт с сообщением(“server error”) и типом(“error) и по колбеку спрятали через 3 секунды. Алерт не виден и ждет нового вызова из любого компонента.
Сохранять стейт — это прикольно. Но контекстные данные не должны сохраняться, если контекст изменился. Это же просто нелогично.
Спасибо за ответ. Не могли бы прокомментировать последний абзац? Как это выглядит при использовании Redux? В данный момент, в моих приложениях, когда с сервера прилетают данные я диспатчу экшн и в payload я кладу какую-то информацию. Это означает, что ответы сервера сохраняются в store. Как можно сделать по-другому? Возможно можете порекомендовать какие-то статьи почитать, чтобы лучше понять вашу мысль.
WeReng, сохранять стейт — это хорошо. Но нужно понимать — когда этого делать не нужно.
Не нужно сохранять стейт при ошибках. Человек ушел с экрана — ошибка должна исчезнуть.
Но если человек писал комментарий, ушел с экрана, вернулся обратно, а недописанный комментарий сохранился в инпуте — это прикольно. Я делал так в одном редакторе постов — все данные до момента публикации или сохранения в черновики сохраняются в окне редактора. Можно обновить страницу, можно вообще выйти из приложения — вернувшись в редактор юзер увидит то, что было написано до этого.
Короче :) отвечая на ваш вопрос — удаляйте ошибку при размаунте основного компонента. Или ставьте колбек по таймауту на скрытие.