Redux Observable используется для проверки формы - PullRequest
0 голосов
/ 03 января 2019

У меня есть пошаговый процесс 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;
...