Search code examples
reactjstypescriptgrommet

Creating a controlled form with Grommet throws errors


I am trying to create a basic form using Grommet following the examples at https://v2.grommet.io/form. My specific form looks like this:

import React from 'react';
import { Box, Form, FormField, TextInput, Button } from 'grommet';

const defaultValue = {};

const LoginForm = () => {
  const [value, setValue] = React.useState(defaultValue);

  function handleSubmit(e) {
    e.preventDefault();
    const { email, password } = e.value;
    console.log('pretending to log in:', email, password);
    // doLogin(email, password)
  }

  return (
    <Form
      value={value}
      onChange={nextValue => {
        setValue(nextValue);
      }}
      onReset={() => setValue(defaultValue)}
      onSubmit={handleSubmit}
    >
      <FormField label="email" name="email" required>
        <TextInput name="email" />
      </FormField>
      <FormField label="password" name="password" required>
        <TextInput name="password" />
      </FormField>
      <Box direction="row" justify="between" margin={{ top: 'medium' }}>
        <Button type="reset" label="Reset" />
        <Button type="submit" label="Login" primary />
      </Box>
    </Form>
  );
};

As soon as I start typing into either field, I get the following:

Warning: A component is changing an uncontrolled input of type undefined to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: ...

Note that I get the exact same error if I replace my form code with a cut/paste from the example in the link above.

I have a fairly reasonable understanding of what the error means, but I have no idea how to fix it in this case. Is Grommet's implementation of controlled form components broken, or am I missing something elsewhere in my configuration or packages that might be causing this?


Solution

  • The React.js controlled standards are not allowing objects to be undefined. So the problem starts with how you've defined your defaultValue = {};, since it is an empty object, there is no initial value to the FormField children and that causes them to be undefined and hence the error. So if you'll change the preset value to be more accommodating to your fields, such as defaultValue = { password: '' }; it will fix your error.

    For more reading about React controlled and uncontrolled inputs read this A component is changing an uncontrolled input of type text to be controlled error in ReactJS