3
votes

I am trying to use a custom Radio component with React-final-form but it is not acting as a radio button but as a checkbox, ie, all the buttons are open for selection.

The 3rd party Radio button has the following schema:

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

I created a custom Component for using the Radio Component:

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

and I am using it as follows:

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

Being very new to RFF and new to React, I may be doing something very wrong, hence any help will be appreciated.

Basically, I want to use RFF with my 3rd party components. Though I have been successful to use my Input component with RFF as expected, Radio Button is the one creating problems.

1
May be you need to add type="radio" to the Field? - jupiteror

1 Answers

0
votes

Here is the correct implementation for Radio with react-final-form:-

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"));