75 lines
1.9 KiB
JavaScript
75 lines
1.9 KiB
JavaScript
import { useState, useEffect, useRef } from "react";
|
|
import Autocomplete from "@mui/material/Autocomplete";
|
|
import TextField from "@mui/material/TextField";
|
|
|
|
/**
|
|
* 一个可复用的 Autocomplete 组件,增加了 name 属性和标准化的 onChange 事件
|
|
* @param {object} props - 组件的 props
|
|
* @param {string} props.name - 表单字段的名称,会包含在 onChange 的 event.target 中
|
|
* @param {string} props.label - TextField 的标签
|
|
* @param {any} props.value - 受控组件的当前值
|
|
* @param {function} props.onChange - 值改变时的回调函数 (event) => {}
|
|
* @param {Array} props.options - Autocomplete 的选项列表
|
|
*/
|
|
export default function ReusableAutocomplete({
|
|
name,
|
|
label,
|
|
value,
|
|
onChange,
|
|
...rest
|
|
}) {
|
|
const [inputValue, setInputValue] = useState(value || "");
|
|
const isChangeCommitted = useRef(false);
|
|
|
|
useEffect(() => {
|
|
setInputValue(value || "");
|
|
}, [value]);
|
|
|
|
const triggerOnChange = (newValue) => {
|
|
if (onChange) {
|
|
const syntheticEvent = {
|
|
target: {
|
|
name: name,
|
|
value: newValue,
|
|
},
|
|
};
|
|
onChange(syntheticEvent);
|
|
}
|
|
};
|
|
|
|
const handleBlur = () => {
|
|
if (isChangeCommitted.current) {
|
|
isChangeCommitted.current = false;
|
|
return;
|
|
}
|
|
|
|
if (inputValue !== value) {
|
|
triggerOnChange(inputValue);
|
|
}
|
|
};
|
|
|
|
const handleChange = (event, newValue) => {
|
|
isChangeCommitted.current = true;
|
|
triggerOnChange(newValue);
|
|
};
|
|
|
|
const handleInputChange = (event, newInputValue) => {
|
|
isChangeCommitted.current = false;
|
|
setInputValue(newInputValue);
|
|
};
|
|
|
|
return (
|
|
<Autocomplete
|
|
value={value}
|
|
onChange={handleChange}
|
|
inputValue={inputValue}
|
|
onInputChange={handleInputChange}
|
|
onBlur={handleBlur}
|
|
{...rest}
|
|
renderInput={(params) => (
|
|
<TextField {...params} name={name} label={label} />
|
|
)}
|
|
/>
|
|
);
|
|
}
|