如何使用带有react-final-form的自定义无线电组件?

时间:2019-09-25 13:04:38

标签: reactjs react-final-form

我正在尝试使用具有React-final-form形式的自定义Radio组件,但它不是充当单选按钮,而是用作复选框,即所有按钮都处于打开状态以供选择。

第三方单选按钮具有以下架构:

checked boolean     
Whether or not radio is checked

onChange    () => void      
Called when the user attempts to change the checked state

name    string      
The input name, used to reference the element in JavaScript

我创建了一个自定义组件以使用Radio组件:

const CustomRadio = (props: any) => (
    <Radio
        {...props.input}
        {...props.rest}
        name={props.name}
        onChange={() => props.input.onChange()}
    />
)

我正在按如下方式使用它:

<Field name="food"
component={CustomRadio}
value="1"
/>
<Field name="food"
component={CustomRadio}
value="2"
/>

对于RFF来说是新手,对于React来说,我可能做错了很多事情,因此,我们将不胜感激。

基本上,我想将RFF与我的第三方组件一起使用。尽管我已成功按预期将我的Input组件与RFF一起使用,但是Radio Button是一个造成问题的人。

1 个答案:

答案 0 :(得分:0)

这是带有 react-final-form 的 Radio 的正确实现:-

https://codesandbox.io/s/vibrant-easley-5n1ek?file=/index.js

/* eslint-disable jsx-a11y/accessible-emoji */
import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";
import RadioGroup from "@material-ui/core/RadioGroup";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import FormControl from "@material-ui/core/FormControl";
import Radio from "@material-ui/core/Radio";
import FormLabel from "@material-ui/core/FormLabel";


const RadioWrapper = (props) => {
  const {
    input: { checked, value, name, onChange, ...restInput },
  } = props;

  return (
    <Radio
      name={name}
      inputProps={restInput}
      onChange={onChange}
      checked={checked}
      value={value}
    />
  );
};

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const onSubmit = async (values) => {
  await sleep(300);
  window.alert(JSON.stringify(values, 0, 2));
};

const App = () => {
  return (
    <Styles>
      <h1>React Final Form - Simple Example</h1>
      <a
        href="https://final-form.org/react"
        target="_blank"
        rel="noopener noreferrer"
      >
        Read Docs
      </a>
      <Form
        onSubmit={onSubmit}
        initialValues={{
          employed: false,
          all_sub_tenants: "true"
        }}
        render={({ handleSubmit, form, submitting, pristine, values }) => (
          <form onSubmit={handleSubmit}>
            <FormControl component="fieldset">
              <FormLabel component="legend">
                Select Tenants
              </FormLabel>
              <RadioGroup aria-label="allSubTenants" name="allSubTenants">
                <FormControlLabel
                  value="true"
                  control={
                    <Field
                      name="all_sub_tenants"
                      component={RadioWrapper}
                      type="radio"
                      value={"true"}
                    />
                  }
                  label="All Sub-Tenants"
                />
                <FormControlLabel
                  value="false"
                  control={
                    <Field
                      name="all_sub_tenants"
                      component={RadioWrapper}
                      type="radio"
                      value={"false"}
                    />
                  }
                  label="Select Sub-Tenants"
                />
              </RadioGroup>
            </FormControl>
            
            <div>
              <label>Notes</label>
              <Field name="notes" component="textarea" placeholder="Notes" />
            </div>
            <div className="buttons">
              <button type="submit" disabled={submitting || pristine}>
                Submit
              </button>
              <button
                type="button"
                onClick={form.reset}
                disabled={submitting || pristine}
              >
                Reset
              </button>
            </div>
            <pre>{JSON.stringify(values, 0, 2)}</pre>
          </form>
        )}
      />
    </Styles>
  );
};

render(<App />, document.getElementById("root"));