Документація React пропонує думати про інтерфейс декларативно: не «що змінити після кліку», а «які візуальні стани бувають і що переводить з одного в інший».
Процес:
- перелічити візуальні стани: форма відповіді на питання -
empty(поле порожнє),typing,submitting,error,success; - визначити, що їх змінює: введення тексту, натискання «Надіслати», відповідь сервера (успіх чи помилка);
- описати стан мінімальним набором змінних без суперечностей;
- підключити обробники, що змінюють стан.
Редуктор як скінченний автомат:
function quizReducer(state, event) {
switch (state.status) {
case 'typing':
if (event.type === 'submit') return { ...state, status: 'submitting' };
if (event.type === 'change') return { ...state, answer: event.value };
return state;
case 'submitting':
if (event.type === 'resolved') return { ...state, status: 'success' };
if (event.type === 'rejected') return { ...state, status: 'typing', error: event.error };
return state; // під час відправки зміна тексту ігнорується
case 'success':
return state; // кінцевий стан
default:
return state;
}
}
Головна відмінність від звичайного редуктора - перевірка поточного стану перед обробкою події. Подія, недопустима в цьому стані, просто ігнорується: подвійне натискання «Надіслати» під час відправки не створить другий запит.
Що це дає:
- неможливі переходи неможливі: не можна «надіслати» з
success, змінити текст під часsubmitting; - інтерфейс - функція від стану:
disabled={state.status === 'submitting'}, повідомлення про успіх лише вsuccess; - легко тестувати: редуктор - чиста функція, перелік станів і переходів можна перевірити повністю;
- легко побачити всі стани: для кожного з них можна відрендерити компонент окремо (наприклад, у Storybook) і перевірити дизайн.
Коли брати бібліотеку (XState): паралельні й вкладені стани, таймери й затримки як частина логіки, складні багатокрокові процеси (онбординг, оформлення замовлення з кількома способами оплати), потреба візуалізувати автомат для команди.
Для простих компонентів досить одного поля status замість кількох булевих прапорців - це вже більша частина користі.