Проверка формы жизненно важна, потому что она помогает с UX. Это помогает пользователю понять, что что-то не так с тем, что он ввел, что-то упустил и т. Д.
«Надежная» проверка формы помогает (по крайней мере):
- Проверка на стороне клиента: например, Проверьте пустые поля, длину пароля и т. Д.
- Мгновенная проверка на стороне сервера: например, Мгновенно проверьте сервер, если имя пользователя уникально при размытии.
- Проверка на стороне сервера OnSubmit: например, Проверить сервер после отправки
- Предотвращение повторной отправки: например, Отключите кнопку отправки после отправки.
Но реализация такой проверки формы - это большая работа в любом фреймворке, включая приложения Redux. Итак, как вы выполняете проверку формы в приложениях React Redux?
Используйте библиотеки 🎉😀! После некоторого исследования мне понравился: redux-form. Мне он нравится, потому что он надежен и идеально подходит для разработки приложений React-Redux.
Обновление (30 ноября 2016 г.): код пришлось переписать, поскольку библиотека redux-forum претерпела значительные изменения. Таким образом, хотя общая логика остается прежней, последний код в этом блоге больше не соответствует!
Хорошо, давайте посмотрим, как реализовать все эти сценарии на примере приложения.
Примечание: нажмите на картинку выше, чтобы увеличить и прочитать.
Я буду использовать то же приложение для многостраничного блога из Руководства по созданию приложения React Redux CRUD ».
Исходный код: https://github.com/rajaraodv/react-redux-blog
Приложение Live: https://protected-escarpment-79486.herokuapp.com/posts/new
Twitter: https://twitter.com/rajaraodv (@rajaraodv)
Быстрое освежение
Если вы не читали Руководство по созданию приложения CRUD на React Redux, вот вам быстрое обновление.
- Это простое приложение CRUD, которое позволяет нам перечислять, создавать и удалять сообщения в блогах. Мы добавим проверку формы в компонент PostsForm, который фактически создает новую публикацию.
2. Компонент PostsForm является «презентационным» компонентом. Его задача - просто отобразить страницу и делегировать обработку событий ее родительскому компоненту «PostsFormContainer».
3. PostsFormContainer имеет всю логику JS, а также работает с Redux. Он также передает результат обратно в контейнер PostsForm.
Реализация redux-form
redux-form просто украшает (добавляет больше возможностей) компонент. Он поставляется с редуктором, который изменяет состояние формы, и собственным генератором компонентов контейнера , аналогичным собственному «connect ». Ниже приведены шаги по внедрению его в любую обычную форму:
- Добавьте редуктор в наш список редукторов.
- Обновить компонент контейнера : Заменить функцию «connect» из redux на функцию из redux-form. Примечание: redux-form после оформления нашей формы будет внутренне вызывать функцию «connect» Redux.
- Обновить презентационный компонент: Redux-form передает дополнительные свойства и функции обратного вызова презентационным компонентам, которые можно использовать для отображения ошибки, делегирования onSubmit и т. Д.
1. Реализация redux-form - добавление редуктора
import { combineReducers } from ‘redux’; import PostsReducer from ‘./reducer_posts’; import { reducer as formReducer } from ‘redux-form’; //combineReducers adds all reducers into a single JSON of reducers const rootReducer = combineReducers({ posts: PostsReducer, //← Posts form: formReducer // ← redux-form }); export default rootReducer;
2: Реализация redux-form - обновление компонента контейнера
Нажмите на картинку ниже, чтобы сравнить * до * и * после * PostsFormContainer
3. Реализация redux-form - обновление презентационного компонента
Нажмите на картинку ниже, чтобы сравнить * до * и * после * PostsForm. Я подробно рассмотрю каждое изменение в следующих разделах.
Сценарий 1. Добавьте проверку на стороне клиента
Нам нужно обновить компоненты PostsFormContainer и PostsForm, чтобы добавить эту проверку.
Каждый сценарий следует одному и тому же набору шагов
ШАГ 1.1. Проверка на стороне клиента - обновление PostsformContainer
В PostsFormContainer просто добавьте функцию, вызывающую размытие в любом поле. Он получает объект «значения», который содержит текущие значения всех полей. Его задача - проверять наличие ошибок и возвращать их, как показано ниже:
//Client side validation function validate(values) { const errors = {}; if (!values.title || values.title.trim() === ‘’) { errors.title = ‘Enter a Title’; } if (!values.categories || values.categories.trim() === ‘’) { errors.categories = ‘Enter categories’; } if(!values.content || values.content.trim() === ‘’) { errors.content = ‘Enter some content’; } return errors; }
Затем добавьте функцию проверки «проверить» и список полей для отслеживания в сокращенную форму.
Примечание. Чтобы использовать аббревиатуру ES6, имя функции должно быть «проверить».
export default reduxForm({ form: ‘PostsNewForm’, // ←A Unique name fields: [‘title’, ‘categories’, ‘content’], //←Fields to track validate //← Callback function for client-side validation }, mapStateToProps, mapDispatchToProps)(PostsForm);
ШАГ 1.2 Проверка на стороне клиента - Обновите PostForm
Получите новые реквизиты «fields» и «handleSubmit» из redux-формы.
const {fields: { title, categories, content }, handleSubmit} = this.props;
Вместо прямого вызова createPost делегируйте его функции handleSubmit.
<form onSubmit={handleSubmit(this.props.createPost.bind(this))}>
Полученные нами поля реквизитов (заголовок, категории, контент) на самом деле являются объектом, который содержит:
1. Несколько прослушивателей событий, например «onBlur», «onClick» и т. Д. И
2. состояние поля, например, если в нем есть ошибки, было ли поле нажато (затронуто) и т. Д.
Обновите каждое поле, чтобы использовать эти реквизиты, используя оператор «распространения» ({… title}), как показано ниже. Также добавьте любой дополнительный HTML-код для отображения ошибки.
<input type=”text” className=”form-control” {…title} /> <div className=”help-block”> {title.touched ? title.error : ‘’} </div>
Сценарий 2: Добавить мгновенную проверку сервера
Поскольку нам нужно будет выполнить вызов сервера, нам нужно добавить кучу действий и редукторов, чтобы другие компоненты знали, что происходит, на случай, если они будут заинтересованы (или для будущих целей).
ШАГ 2.1 Создание действий, создателей действий и редукторов
Я использую шаблон асинхронного действия, описанный в Руководстве по созданию приложения CRUD React Redux »
В нашем приложении у нас есть следующие действия: VALIDATE_POST_FIELDS, VALIDATE_POST_FIELDS_SUCCESS, VALIDATE_POST_FIELDS_FAILURE, RESET_POST_FIELDS.
У нас также есть соответствующие «Создатели действий» и «редукторы» для всех 4 действий.
Смотрите исходный код здесь: Action Creators и Reducers.
ШАГ 2.2 Мгновенная проверка сервера - Добавить обратный вызов
Redux-form нуждается в функции под названием asyncValidate для возврата Promise. А внутри мы можем выполнять наши обычные действия по «отправке», чтобы об этом знали другие компоненты.
Кроме того, вызовите «отклонить» или «решить», чтобы сообщить redux-form о статусе.
//For instant async server validation const asyncValidate = (values, dispatch) => { return new Promise((resolve, reject) => { dispatch(validatePostFields(values)) .then((response) => { let data = response.payload.data; let status = response.payload.status; //if there is an error if(status != 200 || data.title || data.categories....) { //let other comps know of error by updating redux` state dispatch(validatePostFieldsFailure(response.payload)); reject(data); //this is for redux-form itself } else { //let other comps know success by updating redux` state dispatch(validatePostFieldsSuccess(response.payload)); resolve();//this is for redux-form itself } }); //dispatch }); //promise };
ШАГ 2.2 Мгновенная проверка сервера - добавить в конфигурацию Redux-form
Добавьте функцию обратного вызова (asyncValidate), а также добавьте поле для отслеживания специально для мгновенной проверки сервера.
export default reduxForm({ ... asyncValidate, //←A Callback for instant server validation asyncBlurFields: [‘title’], //← Fields to track for instant check ... }, mapStateToProps, mapDispatchToProps)(PostsForm);
ШАГ 2.3 Мгновенная проверка сервера - Обновите PostForm
Redux-form отправляет еще одно свойство с именем «asyncValidating». Это позволяет нам показывать «проверка ..» или какой-то счетчик. Все остальное, например поля, handleSubmit, работает так же, как в сценарии №1.
const {asyncValidating, fields: ..., handleSubmit} = this.props; <div className=”help-block”> {asyncValidating === ‘title’? ‘validating..’: ‘’} </div>
Сценарий 3: Проверка на стороне сервера OnSubmit
Шаги аналогичны сценарию № 2 (Добавить мгновенную проверку). Основное отличие состоит в том, что вы будете использовать это вместе с фактической отправкой сообщения. То есть вы отправите форму, если все в порядке, а затем дождитесь, пока сервер не сообщит об ошибке.
В этом сценарии вам придется проявлять осторожность и различать черно-белые ошибки из-за данных формы и ошибки из-за сервера (500)
Вы, вероятно, воспользуетесь этим, если не хотите (или не можете иметь) мгновенные проверки сервера, но хотите отображать ошибки сервера при отправке.
ШАГ 3.1 Проверка onSubmit - Обновите PostsformContainer
Добавьте функцию для работы с отправкой и ошибками. Он должен вернуть «обещание», а затем реализовать «отклонить» и «разрешить».
//For any field errors upon submission (i.e. not instant check) //Note: In the below function, we kinda assume that the fields are valid and try to create post and handle errors if any later on. const validateAndCreatePost = (values, dispatch) => { return new Promise((resolve, reject) => { dispatch(createPost(values)).then((response) => { let data = response.payload.data; //error.. if(response.payload.status != 200) { //let other components know by updating the redux` state dispatch(createPostFailure(response.payload)); reject(data); //this is for redux-form itself } else { //let other components by updating the redux` state dispatch(createPostSuccess(response.payload)); resolve();//this is for redux-form itself } });//dispatch });//return };
Добавьте функцию в «mapDispatchToProps», поскольку теперь эта функция должна вызываться компонентом PostsForm при нажатии кнопки Отправить.
const mapDispatchToProps = (dispatch) => { return { createPost: validateAndCreatePost, resetMe: () =>{ dispatch(resetNewPost()); } } }
Сценарий 4. Предотвращение повторной отправки
Это довольно просто реализовать. Redux-form передает логическое значение «отправка» компоненту PostsForm. Все, что нам нужно сделать, это обновить нашу кнопку «Отправить», чтобы включить или отключить себя в зависимости от этого.
4.1. Обновить PostsForm
Получите логическое свойство submitting. Он обновляется соответствующим образом и автоматически с помощью redux-form в зависимости от того, отправляем мы или нет.
const {asyncValidating, fields: { title, categories, content }, handleSubmit, submitting } = this.props;
Обновите кнопку «Отправить», как показано ниже:
<button type=”submit” className=”btn btn-primary” disabled={submitting} >Submit</button>
Исходный код: https://github.com/rajaraodv/react-redux-blog
Приложение Live: https://protected-escarpment-79486.herokuapp.com/posts/new
Twitter: https://twitter.com/rajaraodv (@rajaraodv)
На этом пока! 🙏
🎉🎉🎉 Если вам понравился этот пост, ❤❤❤ его ниже и поделитесь им в Twitter (https://twitter.com / rajaraodv ) 🎉🎉🎉
Мои другие блоги
ES6
- 5« плохих частей JavaScript, исправленных в ES6»
WebPack
- Webpack - запутанные части
- Замена Webpack и горячего модуля [HMR]
- HMR и React-Hot-Loader Webpack - Отсутствующее руководство
Draft.js
Реагировать и Redux:
- Пошаговое руководство по созданию приложений React Redux
- Руководство по созданию приложения CRUD на React Redux (трехстраничное приложение)
- Использование промежуточного программного обеспечения в приложениях React Redux
- Добавление надежной проверки формы для реагирования на приложения Redux
- Защита приложений React Redux с помощью токенов JWT
- Обработка транзакционных писем в приложениях React Redux
- Анатомия приложения React Redux
- Почему Redux нужны редукторы, чтобы они были« чистыми функциями »