如何为当前版本Autocomplete封装带状态管理的可复用组件
可复用Autocomplete组件抽离方案
核心思路是把重复的状态定义、值处理逻辑、选项label解析逻辑封装在组件内部,把随业务场景变化的配置(选项数据、标签文本、宽度、默认值、值变更回调等)抽为props,使用时不需要重复编写useState和重复的处理逻辑。
封装后的通用组件代码
import { useState } from 'react'; import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; const CommonAutocomplete = ({ options = [], label = '', width = 300, required = false, defaultValue = '', optionLabelKey = 'firstName', onValueChange = () => {} }) => { // 内部维护选中状态,父组件无需重复定义useState const [selectedValue, setSelectedValue] = useState(defaultValue); // 统一处理freeSolo模式下的值解析逻辑 const handleValueChange = (_, newValue) => { let finalVal; if (typeof newValue === 'string') { finalVal = newValue; } else if (newValue?.inputValue) { finalVal = newValue.inputValue; } else { finalVal = newValue; } setSelectedValue(finalVal); onValueChange(finalVal); }; // 统一处理选项文本解析 const resolveOptionLabel = (option) => { if (typeof option === 'string') return option; if (option.inputValue) return option.inputValue; return option[optionLabelKey]; }; return ( <Autocomplete required={required} value={selectedValue} onChange={handleValueChange} selectOnFocus clearOnBlur handleHomeEndKeys freeSolo options={options} getOptionLabel={resolveOptionLabel} renderOption={(props, option) => <li {...props}>{option[optionLabelKey]}</li>} sx={{ width }} renderInput={(params) => <TextField {...params} label={label} />} /> ); }; export default CommonAutocomplete;
使用方式
使用时不需要单独编写状态管理和重复的处理逻辑,只需要传入对应场景的配置即可:
import CommonAutocomplete from './CommonAutocomplete'; const FormPage = () => { const userOptions = [ {firstName: '张三'}, {firstName: '李四'}, {firstName: '王五'} ]; // 需要获取选中值时,传入回调即可 const handleNameGet = (val) => { console.log('当前选中值:', val); // 在这里写后续业务逻辑,比如表单提交、字段联动 }; return ( <div style={{padding: 24}}> {/* 第一个实例:名 */} <CommonAutocomplete required options={userOptions} label="First Name" onValueChange={handleNameGet} /> {/* 第二个实例:联系人,自定义宽度和默认值 */} <CommonAutocomplete options={userOptions} label="紧急联系人" width={400} defaultValue="张三" /> </div> ); };
可选扩展
- 如果需要支持表单场景下的受控需求(比如外部重置值、批量赋值),可以增加受控逻辑判断:如果父组件传入
value和onChangeprops,就优先使用父组件传入的状态和回调,否则使用组件内部state,同时兼容受控、非受控两种使用模式。 - 如果不同场景下选项渲染、输入框渲染逻辑差异较大,可以把
renderOption、renderInput也作为可选props传入,支持自定义覆盖默认渲染逻辑。 - 固定的全局配置(比如通用宽度、通用校验规则)可以直接写在封装组件内部,减少使用时的重复传参。
内容的提问来源于stack exchange,提问作者Shoppe
相关产品推荐
相关产品推荐

