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

React MUI Autocomplete如何通过Props动态传递选项绑定字段

实现方案

核心问题是你传入的name属性没有被自定义组件内部逻辑消费,且硬编码的字段取值逻辑没有做动态替换,按以下两步修改即可实现多数据源复用:


1. 修改CustomAutoComplete组件

把硬编码的字段、标签全部改为从Props读取,同时兼容freeSolo模式下手动输入字符串的边界场景,避免取值报错:

import Autocomplete from "@mui/material/Autocomplete";
import Box from "@mui/material/Box";
import Stack from "@mui/material/Stack";
import TextField from "@mui/material/TextField";
 
export default function CustomAutoComplete(props) {
  // 从Props解构配置项,optionKeyField默认取id
  const {
    inputValue,
    set,
    data,
    optionLabelField, // 动态传入的绑定字段名,必填
    label, // 输入框标签,必填
    optionKeyField = "id",
    id = "custom-combobox"
  } = props;

  return (
    <Stack sx={{ m: 1 }}>
      <Autocomplete
        sx={{ ml: 2, mr: 2 }}
        size="small"
        id={id}
        freeSolo
        inputValue={inputValue}
        onInputChange={(event, newValue) => {
          set(newValue);
        }}
        // 动态取对应字段的显示值,兼容字符串输入场景
        getOptionLabel={(option) => {
          if (typeof option === "string") return option;
          return option[optionLabelField] ?? "";
        }}
        options={data}
        // 动态判断值相等,兼容字符串输入场景
        isOptionEqualToValue={(option, value) => {
          if (typeof value === "string") {
            return option[optionLabelField] === value;
          }
          return option[optionLabelField] === value[optionLabelField];
        }}
        // 动态渲染选项内容和key
        renderOption={(liProps, option) => (
          <Box component="li" {...liProps} key={option[optionKeyField]}>
            {option[optionLabelField]}
          </Box>
        )}
        renderInput={(params) => <TextField {...params} label={label} />}
      </Autocomplete>
    </Stack>
  );
}

2. 修改父组件调用方式

你之前写的name={region_name}有两个问题:一是region_name是未定义的变量,字符串常量需要加引号;二是组件本身没读取name属性做逻辑处理。调用时传入我们新增的配置Props即可:

import CustomAutoComplete from "../../atoms/AutoComplete";
import FormGroup from "@mui/material/FormGroup";
import { Fragment, useState, useEffect } from "react";
import { useLocalStorage } from "../../utils/LocalStorage.js";

const EventDetails = () => {
  const [region, setRegion] = useLocalStorage("region", "");
  const [regionList, setRegionList] = useState([]);

  // 拉取后端区域数据
  useEffect(() => {
    fetch("/authentication/region")
      .then((response) => response.json())
      .then((res) => setRegionList(res));
  }, []);

  return (
    <Fragment>
      <FormGroup sx={{ p: 2, m: 1 }}>
        <CustomAutoComplete
          inputValue={region}
          set={setRegion}
          data={regionList}
          // 传入绑定的字段名和标签
          optionLabelField="region_name"
          label="Region"
        />
        {/* 后续如果要适配其他数据源,直接传对应字段即可,比如用户列表:
        <CustomAutoComplete
          inputValue={user}
          set={setUser}
          data={userList}
          optionLabelField="user_name"
          label="负责人"
        />
        */}
      </FormGroup>
    </Fragment>
  );
};

注意点

  • 所有动态字段取值都用JS对象的方括号语法obj[fieldName]实现,不要用点语法obj.fieldName,点语法无法读取动态变量对应的属性
  • 因为开启了freeSolo属性,用户可以手动输入不在选项列表里的内容,这时候返回的value是字符串类型,必须加类型判断,否则读取value[optionLabelField]会直接报错
  • 原来硬编码的组件id、输入框label都改成可配置项,避免同一页面引入多个组件时出现id重复、标签固定的问题

内容的提问来源于stack exchange,提问作者euføeni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 15:54:21