我有一个Formik步骤过程。第一步,用户输入名称。我希望在2个场合中异步检查该名称。
首先,当用户停止输入时,我想对呼叫进行退信,直到用户单击Submit
。
当用户单击“提交所有步骤”时,我第二次要检查它。
我正在使用React,Redux,Redux-Observable来实现这一目标。
到目前为止,我已经做过什么,我知道我需要做些什么,但是不确定是否以及如何实现。除了以下内容外,我知道我还需要史诗中的另一个pipe
方法,然后使用反跳运算符。我还在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
};
在史诗中我有这个:
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;