带有自动完成功能的 React Form Hook Material UI

React Form Hook with Autocomplete Material UI

我有一个 countries 数组,其中包含 idname。目前我正在使用 Material UI Autocomplete 元素并且我有一个反应钩子形式。当我提交表单时,我想获取国家 ID。目前它是 posting 国家名称。有没有一种方法可以 post ID 而不是名称,而无需从名称中获取 ID。

   <Autocomplete
      className="form-item"
      options={countries}
      getOptionLabel={option => option.name}
      renderInput={params => (
        <TextField
          {...params}
          inputRef={register}
          label="Country"
          name="country"
          placeholder="Select a Country"
          InputLabelProps={{
            shrink: true
          }}
          variant="outlined"
        />
      )}
    />

恐怕没有 'easy' 方法来获取当前设置的 ID。

但是,您可以挂接到 Autocomplete#onChange 事件并使用 value 属性接管自动完成组件的内部值状态。这导致在您的组件中具有可用的值并利用它来发挥您的优势。

在下面的示例中,表单数据中的 ID 将作为 country-id

function CountryAutocomplete() {
  const [value, setValue] = useState(); // `[]` for multiple

  return (
    <React.Fragment>
      <Autocomplete
        className="form-item"
        value={value}
        onChange={(event, value) => setValue(value)}
        options={countries}
        getOptionLabel={option => option.name}
        renderInput={params => (
          <TextField
            {...params}
            inputRef={register}
            label="Country"
            name="country"
            placeholder="Select a Country"
            InputLabelProps={{
              shrink: true
            }}
            variant="outlined"
          />
        )}
      />
      <input value={value?.id} name="country-id" />
    </React.Fragment>
  );
}

使用 react-hook-form 的 Controller 并将整个 Autocomplete 放在 as 属性中。这样,当您提交表单时,您将获得所选选项的整个对象。

注意:在react-hook-form版本6.x中,onChange is removed,as prop将接受一个函数和您可以获得 onChange 作为参数。

Working demo - v6

    <Controller
        as={({ onChange }) => (
          <Autocomplete
            className="form-item"
            options={countries}
            onChange={(_, data) => onChange(data)}
            getOptionLabel={option => option.label}
            renderInput={params => (
              <TextField
                {...params}
                label="Country"
                placeholder="Select a Country"
                InputLabelProps={{
                  shrink: true
                }}
                variant="outlined"
              />
            )}
          />
        )}
        name="country"
        control={control}
        defaultValue={{ label: "The Shawshank Redemption", id: "1994" }}
      />

注意:如果您使用的是 v5x,请查看下面的演示和代码片段。

Working demo - v5

   <Controller
        as={
          <Autocomplete
            className="form-item"
            options={countries}
            getOptionLabel={option => option.label}
            renderInput={params => (
              <TextField
                {...params}
                label="Country"
                placeholder="Select a Country"
                InputLabelProps={{
                  shrink: true
                }}
                variant="outlined"
              />
            )}
          />
        }
        name="country"
        control={control}
        onChange={([, data]) => data}
        defaultValue={{ label: "The Shawshank Redemption", id: "1994" }}
      />

编辑:基于评论 您可以使用 setValue 基于 api.

设置默认值

代码片段:

useEffect(() => {
    setTimeout(() => { // fake api
      setValue(
        "country",
        { label: "hi The Godfather", id: "1972" },
        { shouldDirty: true }
      );
    }, 2000);
  }, []);

上面的Demo v6已更新。

另见 official demo of setValue usage here