reactjsreact-admincontrolled-component

Controlled TextInput in React-Admin


Before my question is marked as duplicate, I want to clarify I know how to write a controlled input in vanilla/regular React.

The issue I have now is that I expected to be able to do the same thing with React-Admin's TextInput. Using typescript hints, I see that value and onChange are accepted as properties, but they don't control the input.

E.g.

const LowerCaseInput: React.FC = (props) => {
  const [value, setValue] = useState('');

  const handleChange = (event: any) => {
    const val = event.target.value || '';
    setValue(val.toLowerCase()) // Disallow Uppercase characters
  }

  return <TextInput {...props} value={value} onChange={handleChange} />
}

In this example, I can type characters into the TextInput but they are not coerced to lower case. I can console.log() the values and those show up every time I type. Also, switching to a vanilla <input /> allows it to be controlled, i.e. the values are lower case.

Am I supposed to be able to control inputs this way, or is there some other (roundabout method) of doing something fairly standard?


Solution

  • React-Admin uses React-Final-Form to control form inputs internally. Hence, you can use the format() and parse() methods to what you require.

    Giving you an example of a in React-final-form.

    <Field
        name="username"
        component="input"
        type="text"
        placeholder="Username"
        format={(value) => value && value.toUpperCase()}
        parse={(value) => (value ? value.toLowerCase() : "")}
    />
    

    You can use this in react-admin context as well.

    Same is mentioned in the documentation as well. (https://marmelab.com/react-admin/Inputs.html#transforming-input-value-tofrom-record)

    Mnemonic for the two functions:

    1. parse(): input -> record

    2. format(): record -> input

    You can now modify the implementation as per your needs.