Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Material UI Autocomplete using React Hook Forms issue

I am having issues with React Hook Forms with Material UI Components and I can't really find resources on this. I have a page where I fetch the countries and the current profile information and I want to show it inside the form. Initially I want to set the country to Germany.

const [countries, setCountries] = useState([]);
const { control, handleSubmit, register, reset } = useForm();
const [currentProfile, setCurrentProfile] = useState<profiles.resProfileFields>();

useEffect(() => {
  const getProfileData = async () => {
    try {
      const profile = await api.get(profiles.getById, { id: profileId });
      if (profile != null && profile != undefined) {
        setCurrentProfile(profile);
        setcountryId(profile.country.id);
      }

    } catch (err) {
      console.log(`error getting: ${err}`);
    }
  };
  getProfileData();
  getCountries();
}, [profileId]);


useEffect(() => {
  reset(currentProfile);
}, [currentProfile]);

const getCountries = () => {
  api
    .get(routes.countries.list, {})
    .then(res => {
      setCountries(res);
    })
    .catch(err => { });
};

<form onSubmit={handleSubmit(onSubmit)}>


  <TextField
    inputRef={register}
    name="name"
    label="* Name"
    InputLabelProps={{
      shrink: true
    }}
    variant="outlined"
    placeholder="Name"
    className="form-item-full"
  />

  <Controller
    name="country"
    as={
      <Autocomplete
        className="form-item"
        options={countries}
        getOptionLabel={option => option.name}
        renderInput={params => (
          <TextField
            {...params}
            inputRef={register}
            label="Country"
            placeholder="Select a Country"
            InputLabelProps={{
              shrink: true
            }}
            variant="outlined"
          />
        )}
      />
    }
    defaultValue="Germany"
    control={control}
  />
</form>
  1. How can I initially set/reset the value to Germany?
  2. How can I post the Id of the country when I submit?
like image 465
Missak Boyajian Avatar asked Jul 21 '20 08:07

Missak Boyajian


1 Answers

In the codesandbox suggested by Bill you can see an exact example.

The Controller with the Autocomplete component should look like this:

    <Controller
      render={props => (
        <Autocomplete
          {...props}
          options={countries}
          getOptionLabel={option => option.name}
          renderInput={params => (
            <TextField
              {...params}
              label="Country"
              placeholder="Select a Country"
              InputLabelProps={{
                shrink: true
              }}
              variant="outlined"
            />
          )}
          onChange={(_, data) => props.onChange(data)}
        />
      )}
      name="country"
      control={control}
    />

Because the selected country actually is an Object, you will have to set the German country object in the defaultValues:

const { control, handleSubmit, register, reset } = useForm({ 
  defaultValues: {
    country: { name: 'Germany', id: 1234 },
  } 
});

If you don't want to 'hardcode' the country in the defaultValues Object, you could move the getCountries call up one level and pass it to the form. You can now conditionally render the form when all data is available and find the country in the countries list like so:

const MyForm = ({ countries }) => {
  const { control, handleSubmit, register, reset } = useForm({ 
    defaultValues: {
      country: countries.find(({ name }) => name === 'Germany'),
    } 
  });
like image 97
Chris Avatar answered Oct 15 '22 17:10

Chris