#reactjs #typescript #react-hooks
Вопрос:
Давайте представим, что у нас есть следующее состояние с его действиями редуктора
type User = {
id: number
}
type LoginState = {
user?: User,
isLoggingIn: boolean,
isLoggedIn: boolean,
error?: Error
}
type LoginActions =
| { type: 'START_LOGGING_IN' }
| { type: 'SUCCESSFUL_LOG_IN', user: User }
| { type: 'ERROR', error: Error }
| { type: 'START_LOGGING_IN' }
Если я хочу использовать это состояние из всего своего приложения, мне наверняка понадобится какое-то решение для контекста react. Я бы предпочел, чтобы для этого вопроса не использовались какие-либо внешние зависимости.
Однако после некоторого обучения fsharp этот подход приводит к невозможным состояниям. Например, у государства isLoggedIn
может возникнуть ошибка, если мы допустим ошибку в редукторе.
Решение состояло бы в том, чтобы сделать состояние входа дискриминируемым типом объединения, но затем, насколько я проверил типизацию машинописи для пользователя, это заставит меня иметь все свойства в типе, как в примере.
Итак, как обычно решается эта проблема? Я знаю, что пример, который я описал, является стандартным подходом, но тогда, всякий раз, когда я использую состояние входа в систему, мне приходится обрабатывать в каждом месте несуществование пользователя, чего я не хочу. Я хотел бы получить наиболее типобезопасное решение этой проблемы, поэтому также не type assertions
используйте, пожалуйста.
Если я ошибаюсь в некоторых утверждениях, которые я сделал, пожалуйста, поправьте меня, я совсем запутался в интерфейсных материалах :S
Спасибо!
Ответ №1:
Наиболее типобезопасный подход заключается в определении LoginState
как дискриминируемого объединения только допустимых состояний редуктора. Это дает вам возможность определять функции, которые обрабатывают только те типы компонентов объединения, для которых они предназначены.
Хотя обычно это большая суета, и в большинстве случаев разработчики довольно довольны типом LoginState
, определенным в вашем вопросе.
Комментарии:
1. Ммм, я понимаю, проблема с таким подходом заключается в том, что вам все равно придется писать много бесполезных полей для каждого состояния, что на самом деле не масштабируется для более сложных состояний. Я предполагаю, что я просил какую-то машину состояний, такую как Xstate, но тогда почему документы react рекомендуют этот подход для сложных состояний? Более того, почему пользователь не принимает союз государств с разными формами? Логические флаги, где никогда не было действительно чистого решения для представления состояний. Тем не менее, спасибо за вашу ссылку на игровую площадку
2. Ну, вы можете срезать некоторые углы с наследованием интерфейса, но для сложных состояний все равно довольно быстро становится запутанным.