Два показанных вами редуктора будут работать и давать одинаковые результаты, если вы об этом и просите. Я думаю, что теоретическая версия, которую вы получаете из документации, предназначена для демонстрации определенной концепции, которая, возможно, нарушается вашим редуктором (хотя это не так уж и важно; наша задача - создать рабочий код, а не пройти какой-то тест на чистоту). !).
В частности, вы обычно хотите несколько отделить действия от состояния. Действие не должно быть просто отражением вашей структуры данных состояния;если вы хотите эту связь, вы можете использовать useState
вместо этого и просто установить состояние напрямую. Редуктор предназначен для отделения этого, моделируя описание действия, а затем только редуктор решает, как это действие воздействует на состояние. Например, вы можете решить добавить кнопку очистки формы. С вашим текущим шаблоном вам придется отправлять два действия, которые вызовут два обновления состояния, потому что ваши действия тесно моделируют состояние. Шаблон оператора switch позволяет легко применять различные типы логики на основе различных типов действий.
Нет неправильных ответов, просто разные подходы со всеми их достоинствами. Вот один, который, я думаю, предлагает лучшую развязку, позволяя логике редуктора позаботиться о том, является ли поле допустимым:
const SET_FIRST_NAME = Symbol();
const SET_LAST_NAME = Symbol();
const CLEAR_FORM = Symbol();
// Call action creators instead, like: dispatch(setFirstName(e.target.value));
const setFirstName = name => { type: SET_FIRST_NAME, value: name };
const setLastName = name => { type: SET_LAST_NAME, value: name };
const clearForm = () => { type: CLEAR_FORM };
const initialState = {
firstName: { value: '', isValid: false },
lastName: { value: '', isValid: false }
};
const notEmpty = value => !!(value && value.trim().length);
const validateFirstName = notEmpty; // Or replace with different logic
const validateLastName = notEmpty;
const reducer = (state, action) => {
switch (action.type) {
case SET_FIRST_NAME:
return {
...state,
firstName: {
value: action.value,
isValid: validateFirstName(value)
}
}
case SET_LAST_NAME:
return {
...state,
lastName: {
value: action.value,
isValid: validateLastName(value)
}
}
case CLEAR_FORM:
return initialState;
default:
return state;
}
};