使用 FormSpy 时如何禁用 React Final Form 中的提交按钮?

How to disable submit button in React Final Form when FormSpy is used?

我正在使用来自 sharetribe 的模板,我不得不修改 日期可用性过滤器,但是当我想将提交按钮设置为在没有任何内容时禁用时,我卡住了从日期面板中选择。我尝试添加道具 submitting, pristine, invalid 并为此使用它们,但它没有用。 这是代码:

const FilterFormComponent = props => {
  const { liveEdit, onChange, onSubmit, onCancel, onClear, ...rest } = props;

  if (liveEdit && !onChange) {
    throw new Error('FilterForm: if liveEdit is true you need to provide onChange function');
  }

  if (!liveEdit && !(onCancel && onClear && onSubmit)) {
    throw new Error(
      'FilterForm: if liveEdit is false you need to provide onCancel, onClear, and onSubmit functions'
    );
  }

  const handleChange = formState => {
    if (formState.dirty) {
      onChange(formState.values);
    }
  };

  const formCallbacks = liveEdit ? { onSubmit: () => null } : { onSubmit, onCancel, onClear };
  return (
    <FinalForm
      {...rest}
      {...formCallbacks}
      mutators={{ ...arrayMutators }}
      render={formRenderProps => {
        const {
          id,
          form,
          handleSubmit,
          onClear,
          onCancel,
          style,
          paddingClasses,
          intl,
          children,
          submitting
        } = formRenderProps;

        const handleCancel = () => {
          // reset the final form to initialValues
          form.reset();
          onCancel();
        };

        const clear = intl.formatMessage({ id: 'FilterForm.clear' });
        const cancel = intl.formatMessage({ id: 'FilterForm.cancel' });
        const submit = intl.formatMessage({ id: 'FilterForm.submit' });

        const classes = classNames(css.root);

        const spy =
          liveEdit || onChange ? (
            <FormSpy onChange={handleChange} subscription={{ values: true, dirty: true }} />
          ) : null;

          const handleButtonsAvailability = spy ? false : true;

        const buttons = !liveEdit ? (
          <div className={css.buttonsWrapper}>
            <button className={css.clearButton} type="button" onClick={onClear}>
              {clear}
            </button>
            {/* <button className={css.cancelButton} type="button" onClick={handleCancel}>
              {cancel}
            </button> */}
            <button className={css.submitButton} disabled={handleButtonsAvailability} type="submit">
              {submit}           //this is the submit button I want to disable
            </button>
          </div>
        ) : null;

        return (
          <Form
            id={id}
            className={classes}
            onSubmit={handleSubmit}
            tabIndex="0"
            style={{ ...style }}
          >
            <div className={classNames(paddingClasses || css.contentWrapper)}>{children}</div>
            {spy}
            {buttons}
          </Form>
        );
      }}
    />
  );
};

FilterFormComponent.defaultProps = {
  liveEdit: false,
  style: null,
  onCancel: null,
  onChange: null,
  onClear: null,
  onSubmit: null,
};

FilterFormComponent.propTypes = {
  liveEdit: bool,
  onCancel: func,
  onChange: func,
  onClear: func,
  onSubmit: func,
  style: object,
  children: node.isRequired,

  // form injectIntl
  intl: intlShape.isRequired,
};

const FilterForm = injectIntl(FilterFormComponent);

您需要向 FilterForms 组件(使用 React Final Form 组件)添加字段验证。由于字段是通过 props.children 传入的,因此您需要添加 validate 函数来更正字段(处理日期选择器)。

因此,字段有可选的 validate 属性,其工作方式有点像这样

validate={value => (value ? undefined : "Required")}

因此,完成此操作的步骤是:

  1. 为正确的字段添加验证器功能。
  2. 从 formRenderProps 中提取“invalid”值。
  3. 如果“无效”属性为真,则禁用提交按钮。

最后一步需要这样的东西:

<button className={classNames(css.submitButton, {[css.submitButtonInvalid]: invalid })} type="submit" disabled={invalid}>
  {submit}
</button>

在上面的代码中,我假设有 CSS 模块 class: css.submitButtonInvalid 改变了按钮的颜色。

注 1:src/util/validators.js

中有一些现有的验证器

注意 2:您可以通过在本地环境中打开 /styleguide/c/FilterForm/FilterFormExample 页面来玩 FilterForm.example.js。