#reactjs #express #mongoose #redux #redux-form
#reactjs #экспресс #mongoose #redux #redux-form
Вопрос:
У меня есть проверка Joi на моем внутреннем экспресс-сервере. Я могу передавать сообщения проверки из серверной части в объект состояния redux errors, однако как мне правильно настроить это состояние объекта redux, чтобы сообщения на интерфейсе отображались правильно с помощью redux-form. Особенно когда ошибки переключаются с чего-то типа: «требуется имя» на «имя должно состоять как минимум из 2 символов»
Я попытался сделать то, что указано в документах redux-form, импортировав SubmissionError и создав новый объект SubmissionError при возникновении ошибки проверки.
Похоже, что это находится в функции обратного вызова, которая передается redux-forms, владеющей этим методом.props.handleSubmit.
Однако в моем текущем коде я получаю «Нарушение инварианта react-dom.development.js:57 без обнаружения: объекты недопустимы как дочерний элемент React (найдено: объект с ключами {}). Если вы хотели отобразить коллекцию дочерних элементов, используйте вместо этого массив.» Ошибка сейчас,
Компонент, в котором находится входной компонент.
class WorkoutNew extends React.Component {
onSubmit = formValues => {
this.props.createWorkout(formValues, this.props.history);
};
render() {
return (
<div>
<h1 className="title is-3">Create a workout</h1>
<SingleForm onSubmit={this.onSubmit} form="newWorkout" />
</div>
);
}
}
const mapStateToProps = ({ errors }) => {
return { errors };
};
export default connect(
mapStateToProps,
{ createWorkout }
)(withRouter(WorkoutNew));
Повторно использован единый компонент формы ввода. Я передаю form= «value» в качестве реквизитов, чтобы установить для каждого использования этой формы уникальное значение формы.
class SingleForm extends React.Component {
onSubmit = formValues => {
console.log("Form Values", formValues);
console.log("PROPS", this.props);
if (formValues) {
throw new SubmissionError({
name: this.props.errors
});
}
this.props.onSubmit(formValues);
};
render() {
return (
<div>
<form onSubmit={this.props.handleSubmit(this.onSubmit)}>
<Field label="Name" name="name" type="text" component={InputField} />
<button
type="submit"
className="button is-primary is-large"
style={{ marginTop: "20px" }}
>
Submit
</button>
</form>
</div>
);
}
}
const mapStateToProps = ({ errors }) => {
return { errors };
};
export default reduxForm({})(connect(mapStateToProps)(SingleForm));
Здесь я передаю пустой объект, поскольку я использую этот компонент несколько раз, я передаю форму: ‘value’ в качестве реквизита.
Мой создатель действий.
export const createWorkout = (formValues, history) => dispatch => {
axios
.post("/api/workouts", formValues)
.then(res => {
history.push("/workouts");
// Push back to workouts page
})
.catch(err => dispatch({ type: GET_ERRORS, payload: err.response.data }));
};
Чего бы я хотел, так это чтобы при отправке моих входных данных под ними отображалась ошибка проверки на стороне сервера. Эти ошибки также корректно извлекаются в мой объект redux errors.
Ответ №1:
Сохранение эфемерного состояния в redux считается плохой практикой, я бы предложил использовать Formik для сохранения всей логики формы в вашем компоненте, вы также обнаружите, что способ, которым Formik обрабатывает отправленные, позволяет устанавливать ошибки для каждого поля с помощью Formik bag. В качестве альтернативы, я бы посоветовал вам рассмотреть возможность использования Yup для проверки синхронизации на стороне клиента, API почти точно такой же, как Joi. Как указано в репозитории Joi, вам не следует использовать Joi для проверки на стороне клиента, поскольку эта библиотека была разработана с учетом NodeJS.
Комментарии:
1. Что вы имеете в виду, говоря «Сохранение эфемерного состояния в redux — это плохая практика?» Также спасибо за предложения!
2. Это восходит к принципу, что глобальные переменные плохие , Redux — это подробное и структурированное глобальное состояние, и, по словам Дэна Абрамова (создатель), вы должны сохранять только то состояние, которое относится ко всему приложению или которое необходимо обрабатывать сложными способами. короче говоря, если вы можете использовать локальное состояние, используйте локальное состояние, не навязывайте менталитет, делающий все доступным глобально