Проблема заключается в том, что вы запускаете рендеринг каждый раз при вызове setState
, что вызывает неконтролируемое состояние состояния :) Вам необходимо заменить useState
на useReducer .Таким образом, вы сможете обновить весь набор свойств за один повторный рендеринг.Чтобы использовать useReducer
, вам нужно написать редуктор раньше.
function reducer(state, action) {
switch (action.type) {
case 'YOUR_ACTION_TYPE':
return {
...state,
extraCarFields: false,
extraOtherFields: true,
extraOtherFieldsData: action.extraFields
finalCategory: value
};
default:
throw new Error();
}
}
После этого инициализируйте его
const [state, dispatch] = useReducer(reducer, initialState);
Тогда, например, вместо
setState(prevState => ({ ...prevState, extraCarFields: false }))
setState(prevState => ({ ...prevState, extraOtherFields: true }))
setState(prevState => ({ ...prevState, extraOtherFieldsData: loadExtraFields(otherFields) }))
setState(prevState => ({ ...prevState, finalCategory: value }))
Вы будетеdo
const extraFields = loadExtraFields(otherFields);
dispatch({ type: "YOUR_ACTION_TYPE", extraFields: extraFields });
Также рекомендую прочитать обо всех доступных стандартных крючках .Я думаю, что вы, вероятно, будете использовать useCallback
для запоминания ваших функций, а не для инициализации их при каждом рендеринге.И вторая рекомендация - перейти к async , ожидать , чтобы выполнить правильное поведение при загрузке ExtraFields перед отправкой обновления в состояние.
ОБНОВЛЕНИЕ
Для обновления значений в форме я использую такой шаблон:
const reducer = (state, action) => {
switch (action.type) {
case "UPDATE_FIELD":
return {
...state,
[action.prop]: action.value
};
default:
return state;
}
};
...
const handleChange = prop => e => {
const { value } = e.target;
dispatch({ type: "UPDATE_FIELD", prop: prop, value: value });
};
...
<TextField
label="Your email address"
name="email"
type="email"
value={state.email}
onChange={handleChange('email')}
required autoFocus fullWidth />
Таким образом, вы просто передаете имя вашей собственности handleChange
function и json magic сделают все остальное :) Не стесняйтесь задавать дополнительные вопросы, если я что-то пропустил.