Разница в доступе к реквизитам после изменения в хранилище redux между компонентом класса React и функциональным компонентом React
У меня проблема с пониманием, почему в компоненте на основе класса и функциональном компоненте одни и те же шаги приводят к разному результату. Ниже у меня есть пример, демонстрирующий эту разницу.
class Test extends Component {
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields(async (err, values) => {
await this.props.saveUserDetailsAction(values);
const { error } = this.props; // expected modified prop
if (!error.status) {
this.props.router.push("/route");
}
});
};
}
const mapStateToProps = ({ app }) => ({
error: app.error
});
const mapDispatchToProps = {
saveUserDetailsAction,
};
export default compose(
withRouter,
connect(
mapStateToProps,
mapDispatchToProps
)
)(Test);
Текущая ошибка в компоненте класса отражает изменения в хранилище redux после завершения асинхронной функции saveUserDetailsAction, в этом случае отправляя действие в случае сбоя запроса.
Доступ к реквизитам ошибок после того, как функция saveUserDetailsAction показывает обновленное свойство.
Тот же код, написанный как функциональный компонент, не дает такого же результата. Доступ к опоре ошибки после завершения функции saveUserDetailsAction еще не отражает изменения в хранилище.
const Test = (props) => {
const handleSubmit = e => {
e.preventDefault();
props.form.validateFields(async (err, values) => {
await props.saveUserDetailsAction(values);
const { error } = props; // unchanged prop when accessed here
if (!error.status) {
props.router.push("/route");
}
});
};
}
const mapStateToProps = ({ app }) => ({
error: app.error
});
const mapDispatchToProps = {
saveUserDetailsAction,
};
export default compose(
withRouter,
connect(
mapStateToProps,
mapDispatchToProps
)
)(Test);
1 ответ
На мой взгляд, это антипаттерн, вам нужно дождаться следующего цикла, чтобы получить правильные пропсы ошибок. Функциональная составляющая - это правильное поведение. Что вам нужно сделать, так это найти способ вернуть здесь ошибку:
const { error } = await props.saveUserDetailsAction(values);
Переменная ошибки хранилища Redux все еще может использоваться в другом компоненте
Другой способ сделать это - использовать useEffect(() => {}, [error])
и различать 3 состояния "Еще не отправлено", "Отправлено без ошибок", "Отправлено с ошибкой", но я не рекомендую это