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

如何用JoyUI Autocomplete结合react-hook-form实现显示与提交值分离?

解决方案:JoyUI Autocomplete 结合 react-hook-form 实现显示label提交param值

完全可以实现你要的效果,核心是用react-hook-form的Controller组件适配Autocomplete的受控逻辑,同时做好显示字段和提交值的映射。修改你的Input组件如下:

import { Controller } from "react-hook-form";
import { Autocomplete, FormControl, FormLabel, TextField } from "@mui/joy"; // 按你的JoyUI实际导入路径调整

export const Input = ({ label, param, validation, list, control }) => (
  <FormControl>
    <FormLabel>{label}</FormLabel>
    <Controller
      name={param}
      control={control}
      rules={validation}
      render={({ field: { onChange, value } }) => (
        <Autocomplete
          options={list}
          getOptionLabel={(option) => option.label} // 指定界面显示选项的label字段
          value={list.find(opt => opt.param === value) || null} // 根据表单存的param值匹配对应选项对象
          onChange={(_, selectedOption) => {
            // 把选中选项的param值提交给表单
            onChange(selectedOption ? selectedOption.param : null);
          }}
          renderInput={(params) => <TextField {...params} />} // 必须配置,渲染Autocomplete的输入框
        />
      )}
    />
  </FormControl>
);

关键调整说明:

  • 替换register为Controller:Autocomplete是受控组件,Controller能更精准地处理它和react-hook-form的状态同步,直接用register无法完成对象到单一param值的转换。
  • getOptionLabel:明确告诉Autocomplete每个选项要展示的文本是label字段。
  • value映射:表单存储的是param字符串,所以需要从选项列表中找到对应param的对象,作为Autocomplete的选中值。
  • onChange转换:用户选择选项时,只把选项的param值传递给表单,而非整个选项对象。
  • renderInput:JoyUI的Autocomplete必须通过该属性渲染输入框,这里用JoyUI的TextField适配。

父组件使用调整:

需要把react-hook-form的control属性传递给Input组件,替代之前的register:

// 父组件示例
import { useForm } from "react-hook-form";
import { Input } from "./Input";

const statusOptions = [
  { label: "Todo", param: "TODO" },
  { label: "In Progress", param: "IN_PROGRESS" },
  { label: "Ended", param: "ENDED" },
];

export const MyForm = () => {
  const { control, handleSubmit } = useForm();

  const onSubmit = (data) => {
    console.log(data); // 这里会看到status字段的值是TODO/IN_PROGRESS/ENDED
    // 后续提交到API的逻辑
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Input
        label="状态"
        param="status"
        validation={{ required: "状态不能为空" }}
        list={statusOptions}
        control={control} // 传递control替代register
      />
      <button type="submit">提交</button>
    </form>
  );
};

这样就能实现和HTML select一致的效果:界面显示选项的label,提交时向react-hook-form传递对应的param值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:52:35