I'm currently trying to create a dynamic select/input component where you can choose values from select options or type your own value inside an input field by selecting the "other" select option.
Right now I get stuck by updating the form data equally to the value of the selected option / input value. The Form Data Value always persist on the initial / default value.
App.js
...
export default function App() {
  const methods = useForm({});
  const { handleSubmit } = methods;
  const customSalutationOptions = [
    { title: "Not specified", value: "null" },
    { title: "Male", value: "male" },
    { title: "Female", value: "female" }
  ];
  const defaultValues = {
    salutation: "null"
  };
  const onSubmit = (data) => {
    console.log(data);
  };
  return (
    <div className="App">
      <FormProvider {...methods}>
        <form onSubmit={handleSubmit(onSubmit)}>
          <SelectOrInput
            variant="outlined"
            name={`contactPerson[0].salutation`}
            defaultValue={defaultValues}
            selectOptions={customSalutationOptions}
          />
          <Button type="submit" color="primary" fullWidth variant="contained">
            Submit
          </Button>
        </form>
      </FormProvider>
    </div>
  );
}
components/SelectOrInput.tsx
...
type Props = {
  name: string;
  label: string;
  selectOptions: [{ title: string; value: string }];
  defaultValue: any;
  shouldUnregister: boolean;
  variant: "filled" | "outlined" | "standard";
};
export default function SelectOrInput({
  name,
  label,
  selectOptions,
  defaultValue,
  shouldUnregister,
  variant
}: Props) {
  const classes = useStyles();
  const { control } = useFormContext();
  const [showCustomInput, setShowCustomInput] = useState(false);
  const [value, setValue] = useState(selectOptions[0].value);
  const additionalInput = [{ title: "Other", value: "" }];
  const combindedOptions = selectOptions.concat(additionalInput);
  const handleInputSelectChange = (
    event: React.ChangeEvent<{ value: unknown }>
  ): void => {
    const value = event.target.value as string;
    if (value === "") {
      const newState = !showCustomInput;
      setShowCustomInput(newState);
      console.log(value);
      setValue(value);
    } else {
      setValue(value);
    }
  };
  const resetCustomInputToSelect = (event: React.MouseEvent<HTMLElement>) => {
    const newState = !showCustomInput;
    setValue(combindedOptions[0].value);
    setShowCustomInput(newState);
  };
  return (
    <>
      {showCustomInput ? (
        <FormControl className={classes.input}>
          <Controller
            name={name}
            control={control}
            shouldUnregister={shouldUnregister}
            render={({ field }) => (
              <TextField
                {...field}
                label={label}
                InputLabelProps={{ shrink: true }}
                variant={variant}
                placeholder="Other..."
                autoFocus
                type="text"
                onChange={handleInputSelectChange}
                value={value}
                InputProps={{
                  endAdornment: (
                    <InputAdornment position="end">
                      <IconButton
                        size="small"
                        onClick={resetCustomInputToSelect}
                        id="custominput-closebutton"
                      >
                        <CloseIcon fontSize="small" />
                      </IconButton>
                    </InputAdornment>
                  )
                }}
              ></TextField>
            )}
          />
        </FormControl>
      ) : (
        <FormControl className={classes.input} variant={variant}>
          <InputLabel id={`label-select-${label}`}>{label}</InputLabel>
          <Controller
            name={name}
            defaultValue={defaultValue}
            control={control}
            shouldUnregister={shouldUnregister}
            render={({ field }) => (
              <Select
                {...field}
                label={label}
                labelId={`label-select-${label}`}
                value={value}
                MenuProps={{
                  anchorOrigin: {
                    vertical: "bottom",
                    horizontal: "left"
                  },
                  getContentAnchorEl: null
                }}
                onChange={handleInputSelectChange}
              >
                {combindedOptions.map((option, index) => (
                  <MenuItem key={option.title} value={`${option.value}`}>
                    {option.title}
                  </MenuItem>
                ))}
              </Select>
            )}
          />
        </FormControl>
      )}
    </>
  );
}
...
To give a better example I provided a CSB:

 
    