Comments 15
Не важно уже о чем статья, картинку да побольше, к теме максимально не относящуюся.
Человек старался и, в принципе, добротную статью написал. Нет, пофиг, давайте про картинки с самолетами будем говорить.
Скажу за себя и еще вот за тех вот двух — спасибо!
Спасибо за статью)
Интересно было бы еще узнать, как быть в случае с redux. Есть ли способы так же единообразно обрабатывать ошибки? Да, почти вся логика уходит в action-ы и reducer-ы, что позволяет обрабатывать их императивно, но при написании тех же запросов получения данных появляется довольно много бойлерплейта.
Была идея использовать отдельный action на обработку ошибок по http коду, а прочие исключение сводить к ним, но данное решение выглядит несколько криво, да и не особо удалось в силу того, что на беке ошибки контекстно зависели от запроса.
Интересно было бы еще узнать, как быть в случае с redux. Есть ли способы так же единообразно обрабатывать ошибки
Давно пришёл к схеме, в которой совсем не разочаровался и проверил на практике, — не хранить ошибки и временные штуки вроде isLoading полей в redux. Совсем не хранить. Хранить только сами данные. Вся эта мышиная возня с временными вещами вроде стадии выполнения api-запросов к серверу в итоге уходит в react-hooks & hocs. И там реализуется куда более простым и наглядным образом.
не хранить ошибки и временные штуки вроде isLoading полей в reduxТут, мне кажется, больше проблема в том, что новички (и я в их числе) в поисках best practices встречаются с популярными, но не самыми лучшими архитектурными решениями.
Лично я в своем проекте использовал пример работы с OpenDota API и уже в процессе работы наткнулся на недостатки, озвученные Вами.
Честно говоря, ни на пример, ни на статью, у меня, к сожалению, не хватает времени и рук. Поэтому опишу суть: чем меньше малозначительных деталей вы храните в redux, тем вам легче живётся. К примеру разного рода state для анимаций там точно хранить не нужно, это просто дико много бойлерплейта, тонны ужасного кода, с которым потом смерть как неприятно работать. И смысла главное во всём этом тоже нет. Тоже самое касается и разных асинхронных штук вроде запросов к серверу. Хранить ответ в redux store чаще всего оправданно и полезно, а вот progress, isLoading, error (тут уже чуть-чуть спорно) — куда проще обрабатывать в локальном стейте. Благо с react-hooks такие вещи писать стало куда проще. Если совсем образно:
const PostsList = ({ posts /* get them from store */, fetchNewPosts }) => {
const { isLoading, fetch, error } = useRequest(fetchNewPosts); // custom hook
useEffect(() => { fetch(); }, []); // fetch on mount
return <div...
}
const withRedux = connect(st => ({ posts: getNewPosts(st) }, { fetchNewPosts });
export default PostsList |> withRedux;
Довольно сложно дать простой рецепт как понять держать это в сторе или нет. Но если очень упрощённо — представьте что вы перегружаете страницу и хотите увидеть её в том же состоянии (словно hot-reloading). Что для этого необходимо — то в store, что мелочь пузатая — то в state. Такие штуки как isLoading не имеют смысла без запроса, а запрос нельзя сохранить, он ведь памят… процесс. А вот его результат можно. Так же и с анимациями. Они есть процесс. Их не храним. Всё скоротечное и\или невоспроизводимое само по себе не храним. С error история почти такая же, ведь если прошлый запрос окончился ошибкой, то не факт что обновив страницу и выполнив его снова он снова закончится ошибкой, да? ;)
Логика примерно такая. Есть костяк, то что мы рисуем в DOM, есть эффекты и связанные с ними вещи.
Ну и useRequest в сильно упрощённом виде:
export default function useRequest(fetchFn) {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const fetch = useCallback(() =>
{
setIsLoading(false);
setError(null);
return fetchFn()
.catch(setError)
.finally(() => setIsLoading(false));
}, [fetch]);
}
Сам по себе редакс — не самое лучшее архитектурное решение.
По поводу Sentry. Мы сталкивались с ситуацией, что у некоторых пользователей переставали работать хттп реквесты после их манкипатчинга. В результате мы вырубили всю магию, оставив лишь ручной перехват onerror.
Формируем стратегию работы с ошибками в React