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

React下拉选择框:如何获取展示数组以外的更多字段?

问题

我有一个包含ID、name和description字段的JSON数组,想做一个下拉选择框,选项里展示name和description,选中时把对应的ID存入rawID状态。现在只能通过在选项里显示ID再拆分提取的方式实现,用户体验很差,选项会显示成raw1: description1 *id number。能不能直接把ID传入点击处理函数?

原始父组件代码:

const form = () => {
   const [allRaws, setAllRaws] = useState([])
   const [rawID, setRawsID] = useState('')
   
   setAllRaws([
    {"ID" : 1, "name" : "raw1", "description" : "description 1"},
    {"ID" : 2, "name" : "raw2", "description" : "description 2"},
    {"ID" : 3, "name" : "raw3", "description" : "description 3"},
   ])

    const handleSelectRaws = (event, value) =>{
        if (value != null){
            const id = value.split("*").pop()
            setRawsID(id)
        }
    }

   return (
       <AutocompleteForm 
                array={allRaws.map((raw) => ([String(raw.name)]+ ": " + String(raw.description) + 
                 "*" + String(raw.id))} 
                label="Pick set of raws" 
                onChange={handleSelectRaws} />}
   )

}

AutocompleteForm组件原始代码:

export default function AutocompleteForm(props) {
   const { label, array, onChange} = props
  
   return (
     <Autocomplete
       disablePortal
       options={array}
       sx={{ width: 300 }}
       renderInput={(params) => <TextField {...params} label={label}
        />}
        onChange={onChange}
     />
   )
 }
解决方案

当然可以直接传递ID,核心是利用Material-UI Autocomplete组件支持对象数组的特性,不用把数据转成带标记的字符串,直接操作原始对象即可,步骤如下:

1. 修改AutocompleteForm组件

让它接收原始对象数组,自定义选项显示内容,并在选中时直接把ID传给父组件:

export default function AutocompleteForm(props) {
  const { label, options, onChange } = props

  return (
    <Autocomplete
      disablePortal
      options={options}
      sx={{ width: 300 }}
      // 自定义选项展示内容,只显示name和description
      renderOption={(props, option) => (
        <li {...props}>
          {option.name}: {option.description}
        </li>
      )}
      renderInput={(params) => <TextField {...params} label={label} />}
      // 选中时提取ID,传给父组件的回调
      onChange={(event, selectedOption) => {
        if (selectedOption) {
          onChange(selectedOption.ID)
        }
      }}
    />
  )
}

2. 修改父组件代码

直接传入原始对象数组,简化选中逻辑:

import { useEffect, useState } from 'react'

const Form = () => {
  const [allRaws, setAllRaws] = useState([])
  const [rawID, setRawID] = useState('')

  // 用useEffect初始化数据,避免组件无限重渲染
  useEffect(() => {
    setAllRaws([
      {"ID" : 1, "name" : "raw1", "description" : "description 1"},
      {"ID" : 2, "name" : "raw2", "description" : "description 2"},
      {"ID" : 3, "name" : "raw3", "description" : "description 3"},
    ])
  }, [])

  // 直接接收选中的ID,更新状态
  const handleSelectRaws = (selectedID) => {
    setRawID(selectedID)
  }

  return (
    <AutocompleteForm 
      options={allRaws} 
      label="Pick set of raws" 
      onChange={handleSelectRaws} 
    />
  )
}

关键修改说明

  • 不再把对象转成带*的字符串,直接传递原始对象数组给Autocomplete,逻辑更清晰
  • 通过renderOption自定义选项的显示内容,完全隐藏ID,提升用户体验
  • Autocomplete的onChange直接拿到选中的对象,提取ID后传给父组件,不用再做字符串拆分操作
  • 修复了父组件中直接在顶层调用setAllRaws的问题,改用useEffect初始化数据,避免无限重渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:40:05