У меня есть пошаговый процесс Formik.На первом шаге пользователь дает имя.Я хочу, чтобы это имя проверялось асинхронно 2 раза.
Во-первых, когда пользователь перестает печатать, я хочу отменить вызов, пока пользователь не нажмет Submit
.
Во второй раз, когда яхочу проверить, когда пользователь нажимает Отправить все шаги.
Я использую React, Redux, Redux-Observable, чтобы это произошло.
Что я уже сделал и что язнаю, что нужно сделать, но не уверен, что и как реализовать.В дополнение к приведенному ниже, я знаю, что мне нужен еще один метод pipe
в эпосе, а затем использовать оператор debounce.Я также читал аналогичный метод на GitHub (https://github.com/redux-observable/redux-observable/tree/master/examples/redux-form), который говорит, как это сделать, с redux-form
, но не уверен, что он применим здесь.
Если кто-нибудь знает, как решить эту проблему, пожалуйста, советуйтеЯ новичок в RxJS и программировании в целом, и это немного ошеломляет. Спасибо ..
Ниже приведен мой код:
Сделано сериюДействия:
export const Type = {
LIST_ITEMS_ATTEMPT: 'LIST_GROUPS_ATTEMPT',
LIST_ITEMS_SUCCESS: 'LIST_ITEMS_SUCCESS',
LIST_ITEMS_FAILURE: 'LIST_ITEMS_FAILURE'
};
const listItems = () => ({ type: Type.LIST_ITEMS_ATTEMPT });
const listItemsSuccess = payload => ({ type: Type.LIST_ITEMS_SUCCESS, payload });
const listItemsFailure = error => ({ type: Type.LIST_ITEMS_FAILURE, error });
export const Actions = {
listItems,
listItemsSuccess,
listItemsFailure
};
В Epics у меня есть это:
import { of } from 'rxjs';
import { switchMap, map, catchError } from 'rxjs/operators';
import { observableFromHttpPromise, combineAndIsolateEpics } from 'util/epicsUtil';
import { Type as ItemsType, Actions as ItemsActions } from '../actions';
const listItemsEpic = (action$, store, deps) =>
action$.ofType(ItemsType.LIST_ITEMS_ATTEMPT).pipe(
switchMap(() =>
observableFromHttpPromise(deps.listItems()).pipe(
map(result => ItemssActions.listItemsSuccess(result && result.data)),
catchError(error => of(ItemsActions.listItemsFailure(error && error.message)))
)
)
);
const itemsSubjectEpics = combineAndIsolateEpics(listItemsEpic);
export default itemsSubjectEpics;
В моем компоненте для формы, которую я использую Formik
:
import React from 'react';
import PropTypes from 'prop-types';
import { Formik } from 'formik';
import * as Yup from 'yup';
import classNames from 'classnames';
import formPropTypes from 'constants/formPropTypes';
const validationSchema = Yup.object().shape({
name: Yup.string()
.trim()
.required('Item name is required.')
});
class ItemsDetailsForm extends React.Component {
handleSubmit = values => {
const { id, onSubmit } = this.props;
onSubmit(id, values);
};
render() {
const { item } = this.props;
return (
<Formik
initialValues={{ ...item }}
onSubmit={this.handleSubmit}
validationSchema={validationSchema}
render={({ values, touched, errors, handleChange, handleBlur, handleSubmit }) => (
<form onSubmit={handleSubmit}>
<div className="row">
<div className="col-md-3">
<div className="form-group">
<label htmlFor="itemName">
Item name <span className="text-danger">*</span>
</label>
<input
type="text"
onChange={handleChange}
onBlur={handleBlur}
value={values.name}
name="name"
className={classNames('form-control', {
'is-invalid': errors.name && touched.name
})}
id="itemName"
placeholder="Placeholder"
/>
{!!errors.name && touched.name && (
<div className="text-danger">{errors.name}</div>
)}
</div>
<div className="form-group">
<label htmlFor="itemDescription">Description</label>
<textarea
onChange={handleChange}
onBlur={handleBlur}
value={values.description}
name="description"
className={classNames('form-control', {
'is-invalid': errors.description && touched.description
})}
id="itemDescription"
rows="3"
placeholder=""
/>
{!!errors.description && touched.description && (
<div className="text-danger">{errors.description}</div>
)}
</div>
<button type="submit">Submit</button>
</div>
</div>
</form>
)}
/>
);
}
}
ItemsDetailsForm.propTypes = {
...formPropTypes,
item: PropTypes.object
};
ItemsDetailsForm.defaultProps = {
item: {
name: '',
description: ''
}
};
export default ItemsDetailsForm;