You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MUI异步Autocomplete配合react-hook-form时表单无法获取组件值

问题原因
  • 你在封装AddressInput组件时重复维护了两份选中值状态:一份是react-hook-form通过Controller管理的表单状态,另一份是组件内部用useState声明的value状态。你自定义的Autocomplete的value和onChange属性覆盖了field对象自带的对应属性,导致选中地址时只更新了组件内部状态,没有同步给react-hook-form的表单实例,所以提交时获取到的data.address始终为undefined。
  • 组件内部维护的value状态和react-hook-form的表单状态完全割裂,没有同步逻辑,外层表单自然无法拿到选中值。
解决方法

直接修改AddressInput组件逻辑,移除冗余的内部选中值状态,将值同步逻辑交给react-hook-form处理,修改后的核心代码如下:

const AddressInput = ({ control, name, ...rest }) => {
  const [inputValue, setInputValue] = React.useState("");
  const [options, setOptions] = React.useState([]);
  const fetch = React.useMemo(
    () =>
      throttle((request) => {
        const getData = getAddress(request?.input);
        getData.then((res) => {
          setOptions(JSON.parse(res)?.candidates);
          return JSON.parse(res).candidates;
        });
      }, 200),
    []
  );

  return (
    <Controller
      name={name}
      control={control}
      defaultValue={null}
      render={({ field }) => {
        React.useEffect(() => {
          let active = true;
          if (inputValue === "") {
            setOptions(field.value ? [field.value] : []);
            return undefined;
          }

          fetch({ input: inputValue }, (results) => {
            if (active) {
              let newOptions = [];
              if (field.value) {
                newOptions = [field.value];
              }
              if (results) {
                newOptions = [...newOptions, ...results];
              }
              setOptions(newOptions);
            }
          });

          return () => {
            active = false;
          };
        }, [field.value, inputValue, fetch]);

        return (
          <Autocomplete
            {...field}
            id="address"
            getOptionLabel={(option) =>
              typeof option === "string" ? option : option.address
            }
            filterOptions={(x) => x}
            options={options}
            autoComplete
            includeInputInList
            filterSelectedOptions
            value={field.value}
            onChange={(event, newValue) => {
              console.log(newValue);
              setOptions(newValue ? [newValue, ...options] : options);
              // 同步选中值到react-hook-form
              field.onChange(newValue);
            }}
            onInputChange={(event, newInputValue) => {
              setInputValue(newInputValue);
            }}
            renderInput={(params) => (
              <TextField {...rest} {...params} variant="outlined" fullWidth />
            )}
            renderOption={(option) => <span>{option.address}</span>}
          />
        )
      }}
    />
  );
};

修改后所有原本用到内部value的地方都替换为field.value,选中值变更时主动调用field.onChange同步给表单实例,提交时就能拿到正确的address值。

内容的提问来源于stack exchange,提问作者aadlc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:48:00