为什么 FieldSelect 返回一个字符串而 FieldCheckbox 返回一个对象?

Why is FieldSelect returning a string while FieldCheckbox returning an object?

Sharetribe 文档中的 FieldSelect 组件返回一个字符串,而 FieldCheckbox 返回一个 JSON 对象。

我希望 FieldSelect 在特定情况下保存一个 JSON 对象。

我该怎么做?

以下是我的代码供参考,

我是 REACT 的新手,非常感谢任何人解释为什么会发生这种情况。

代码调用

<FieldSelect
  name={subGroupCategoryKey}
  id={subGroupCategoryKey}
  label={categoryLabel}
>
  {relevantSubGroupCategoryOptions.map(c => (
    <option key={c.key} value={c.key}>
      {c.label}
    </option>
  ))}
</FieldSelect>

字段选择

import React from 'react';
import PropTypes from 'prop-types';
import { Field } from 'react-final-form';
import classNames from 'classnames';
import { ValidationError } from '../../components';

import css from './FieldSelect.module.css';

const FieldSelectComponent = props => {
  const { rootClassName, className, id, label, input, meta, children, ...rest } = props;

  if (label && !id) {
    throw new Error('id required when a label is given');
  }

  const { valid, invalid, touched, error } = meta;

  // Error message and input error styles are only shown if the
  // field has been touched and the validation has failed.
  const hasError = touched && invalid && error;

  const selectClasses = classNames(css.select, {
    [css.selectSuccess]: valid,
    [css.selectError]: hasError,
  });
  const selectProps = { className: selectClasses, id, ...input, ...rest };

  const classes = classNames(rootClassName || css.root, className);
  return (
    <div className={classes}>
      {label ? <label htmlFor={id}>{label}</label> : null}
      <select {...selectProps}>{children}</select>
      <ValidationError fieldMeta={meta} />
    </div>
  );
};

FieldSelectComponent.defaultProps = {
  rootClassName: null,
  className: null,
  id: null,
  label: null,
  children: null,
};

const { string, object, node } = PropTypes;

FieldSelectComponent.propTypes = {
  rootClassName: string,
  className: string,

  // Label is optional, but if it is given, an id is also required so
  // the label can reference the input in the `for` attribute
  id: string,
  label: string,

  // Generated by final-form's Field component
  input: object.isRequired,
  meta: object.isRequired,

  children: node,
};

const FieldSelect = props => {
  return <Field component={FieldSelectComponent} {...props} />;
};

export default FieldSelect;

字段复选框

import React from 'react';
import { node, string } from 'prop-types';
import classNames from 'classnames';
import { Field } from 'react-final-form';

import css from './FieldCheckbox.module.css';

const IconCheckbox = props => {
  const { className, checkedClassName, boxClassName } = props;
  return (
    <SVG >
    </svg>
  );
};

IconCheckbox.defaultProps = { className: null, checkedClassName: null, boxClassName: null };

IconCheckbox.propTypes = { className: string, checkedClassName: string, boxClassName: string };

const FieldCheckboxComponent = props => {
  const {
    rootClassName,
    className,
    svgClassName,
    textClassName,
    id,
    label,
    useSuccessColor,
    onChange: handleChange,
    ...rest
  } = props;

  const classes = classNames(rootClassName || css.root, className);

  // This is a workaround for a bug in Firefox & React Final Form.
  // https://github.com/final-form/react-final-form/issues/134
  const handleOnChange = (input, event) => {
    const { onBlur, onChange } = input;
    onChange(event);
    onBlur(event);
    handleChange && handleChange(event);
  };

  const successColorVariantMaybe = useSuccessColor
    ? {
        checkedClassName: css.checkedSuccess,
        boxClassName: css.boxSuccess,
      }
    : {};

  return (
    <span className={classes}>
      <Field type="checkbox" {...rest}>
        {props => {
          const input = props.input;
          return (
            <input
              id={id}
              className={css.input}
              {...input}
              onChange={event => handleOnChange(input, event)}
            />
          );
        }}
      </Field>
      <label htmlFor={id} className={css.label}>
        <span className={css.checkboxWrapper}>
          <IconCheckbox className={svgClassName} {...successColorVariantMaybe} />
        </span>
        <span className={classNames(css.text, textClassName || css.textRoot)}>{label}</span>
      </label>
    </span>
  );
};

FieldCheckboxComponent.defaultProps = {
  className: null,
  rootClassName: null,
  svgClassName: null,
  textClassName: null,
  label: null,
};

FieldCheckboxComponent.propTypes = {
  className: string,
  rootClassName: string,
  svgClassName: string,
  textClassName: string,

  // Id is needed to connect the label with input.
  id: string.isRequired,
  label: node,

  // Name groups several checkboxes to an array of selected values
  name: string.isRequired,

  // Checkbox needs a value that is passed forward when user checks the checkbox
  value: string.isRequired,
};

export default FieldCheckboxComponent;

提交表单时,输入的名称是键,值是用户输入的值。

FieldSelect 是 HTML <select name="someName"> 元素的最终表单包装器。该元素当时只能选择一个值,因此提交将包含类似 someName: 'valueOfSelectedOption'.

的内容

FieldCheckbox 是 HTML <checkbox> 元素的包装器。 Final Form 库使用相当广泛使用的“数组”设置来设置具有相同名称的复选框。

我的意思是,如果您的表单有类似 <checkbox name="asdf" value="a"/><checkbox name="asdf" value="b"/> 的内容,并且用户选中了这两个复选框,则提交的值将如下所示:asdf: ["a", "b"].

注意:如果没有 Final Form 库,默认的 HTML 提交输出将是 asdf=a&asdf=b

因此,FieldCheckbox 实际上使用数组作为输出格式而不是 JSON(尽管在这种情况下它们看起来相同)。

这里有几个您可能想要查看的 React Final Form 链接:

如果您想将字段的值更改为默认值以外的值,您应该检查解析(和格式)字段属性: