Goodbye, useState
На днях выложили записи докладов с React Miami. Среди спикеров был David Khourshid с докладом о том, когда не стоит использовать useState.
Основная мысль доклада: useState следует использовать только для локального состояния внутри компонента, и только если это состояние влияет на UI. Для всего остального David предлагает следующие альтернативы:
-
Если переменная не участвует в рендере компонента, то вместо useState можно хранить её в useRef;
-
Стейт, отвечающий за выбранные пользователем фильтры (чекбоксы, селекты и т.д.) можно хранить сразу в адресной строке. Так выбранные значения не будут сбрасываться при обновлении страницы. Для этого есть useSearchParams в Next, useSearchParams в react-router или в remix-run/react (что одно и то же). А, ещё есть useQueryState в nuqs.
-
Состояния для обработки асинхронных вызовов (наши любимые isLoading и isError). Во-первых, естественно, вместо них у нас есть RSC или хотя бы useTransition. Ещё для этого есть useQuery из Tanstack Query, которая под капотом работает на useSyncExternalStore. Во-вторых, вместо использования трёх разных состояний для isLoading, isSuccess и isError гораздо удобнее использовать одну переменную с несколькими возможными значениями. Какой-нибудь status: 'success' | 'error' | 'loading'.
-
Состояния для хранения значений инпутов в формах часто дублируют функциональность браузерной FormData API. Но если этого недостаточно, есть Form из remix-run/react, Server Actions в Next, TanStack Form и React Hook Form.
-
Вместо хранения нескольких отдельных стейтов иногда есть смысл объединять их в объект с полями. Например, использовать [user, setUser] вместо отдельных состояний firstName и lastName. Особенно, если таких состояний у вас не два, а штук десять.
-
Вместо того, чтобы сохранять в useState всякие window.innerWidth и отслеживать их изменения через addEventListener в useEffect, можно использовать subscribe из useSyncExternalStore.
-
Не забываем пользоваться useReducer для описывания логики изменения стейта. Главное не пропустить момент, когда вы изобретёте свой собственный Redux.
Что хочется сказать Отличные советы про useRef или про единую переменную с несколькими значениями — они стоят того, чтобы напоминать о них почаще.
Но вообще удивительно, что у нас во фронтенде на каждую задачу найдётся по 10 библиотек. Из всего доклада только в одном из пунктов чувак предложил нативное решение с FormData API.
С таким количеством вендорных решений ни одна нейросеть не успеет научиться нормально код писать))