在 Material UI 自动完成中显示一个值(而不是标签)
Showing a value (instead of label) on a Material UI Autocomplete
所以我有一个异步组合框,它从 API 中提取选项。选项只是一个 Id 和一个描述。该组件是我显示的用于添加或编辑数据的表单的一部分。我希望看到的是在添加新数据时选项为空,在编辑时选择当前值。相反,它只是显示标签。
这是我的代码,几乎是文档中示例的复制粘贴。
export default function AsyncAutoComplete(props:AsyncAutoCompleteProps) {
const [open, setOpen] = React.useState(false);
const [options, setOptions] = React.useState<EntityWithIdAndDescription[]>([]);
const loading = open && options.length === 0;
React.useEffect(() => {
let active = true;
if (!loading) {
return undefined;
}
(async () => {
props.populateWith().then((options)=> {
if (active) {
setOptions(options);
}})
})();
return () => {
active = false;
};
}, [loading]);
React.useEffect(() => {
if (!open) {
setOptions([]);
}
}, [open]);
return (
<Autocomplete
id="async-autocomplete"
open={open}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
onChange={props.onChange}
getOptionSelected={(option, value) => option.id === value.id}
getOptionLabel={(option) => option.description}
options={options}
loading={loading}
renderInput={(params) => (
<TextField
{...params}
label={props.label}
variant="outlined"
margin="dense"
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</React.Fragment>
),
}}
/>
)}
/>
);
我想要的是将一个 Id 值传递给该组件,并让它将该值的描述显示为所选选项(在进行 API 调用之后)。使用 defaultValue 似乎不起作用。
任何关于修改它或采取不同方法的建议都会有所帮助。
看来您要找的是 controlled component. There's an example of this in Material UI's Autocomplete demo under Playground called controlled.
我不确定您是如何获得要传递给组件的初始值的 id
以表明它是 selected。它可能类似于以下内容。
在您的父组件中为您 select 的值与此 Autocomplete
创建一个单独的状态。事实上,我根本不会有一个名为 AsyncAutocomplete
的单独组件。这样一来,您就可以控制父组件中的所有状态,并且 Autocomplete
组件变得纯粹是展示性的。
在您的 API 调用完成并调用 setOptions(options)
之后,使用您想要显示的值调用 setValue
select编辑。这必须是 EntityWithIdAndDescription
.
类型
为 Autocomplete
组件的 onChange
属性创建一个内联函数,该函数将第二个参数作为 EntityWithIdAndDescription | null
类型。这是 Autocomplete
的 onChange
的要求。以此参数为参数调用 setValue
。
将 options
、value
、onChange
和 loading
作为 props 传递到 Autocomplete
组件中。除了你在代码中所做的,我已经传递的额外道具是:
<Autocomplete
...
disabled={loading}
value={value}
...
/>
告诉我你过得怎么样
const [value, setValue] = useState<EntityWithIdAndDescription | null>(null); // (1)
const [options, setOptions] = useState<EntityWithIdAndDescription[]>([]);
const loading = options.length === 0;
useEffect(() => {
populateWith().then((options)=> {
setOptions(options);
})
// (2)
setValue({
id: "something",
description: "something",
})
return () => {};
}, []);
// (4)
<Autocomplete
id="async-autocomplete"
disabled={loading}
onChange={(event: any, newValue: EntityWithIdAndDescription | null) => {
setValue(newValue); // (3)
}}
getOptionSelected={(option, value) => option.id === value.id}
getOptionLabel={(option) => option.description}
options={options}
loading={loading}
value={value}
renderInput={(params) => (
<TextField
{...params}
label={"My Entities"}
variant="outlined"
margin="dense"
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</React.Fragment>
),
}}
/>
)}
/>
);
代码沙箱
这是一个在我称为 MyAutocomplete
的单独组件中使用 Autocomplete
的示例。它包括一个 API 调用和设置一个值,我想先 selected。
所以我有一个异步组合框,它从 API 中提取选项。选项只是一个 Id 和一个描述。该组件是我显示的用于添加或编辑数据的表单的一部分。我希望看到的是在添加新数据时选项为空,在编辑时选择当前值。相反,它只是显示标签。 这是我的代码,几乎是文档中示例的复制粘贴。
export default function AsyncAutoComplete(props:AsyncAutoCompleteProps) {
const [open, setOpen] = React.useState(false);
const [options, setOptions] = React.useState<EntityWithIdAndDescription[]>([]);
const loading = open && options.length === 0;
React.useEffect(() => {
let active = true;
if (!loading) {
return undefined;
}
(async () => {
props.populateWith().then((options)=> {
if (active) {
setOptions(options);
}})
})();
return () => {
active = false;
};
}, [loading]);
React.useEffect(() => {
if (!open) {
setOptions([]);
}
}, [open]);
return (
<Autocomplete
id="async-autocomplete"
open={open}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
onChange={props.onChange}
getOptionSelected={(option, value) => option.id === value.id}
getOptionLabel={(option) => option.description}
options={options}
loading={loading}
renderInput={(params) => (
<TextField
{...params}
label={props.label}
variant="outlined"
margin="dense"
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</React.Fragment>
),
}}
/>
)}
/>
);
我想要的是将一个 Id 值传递给该组件,并让它将该值的描述显示为所选选项(在进行 API 调用之后)。使用 defaultValue 似乎不起作用。 任何关于修改它或采取不同方法的建议都会有所帮助。
看来您要找的是 controlled component. There's an example of this in Material UI's Autocomplete demo under Playground called controlled.
我不确定您是如何获得要传递给组件的初始值的 id
以表明它是 selected。它可能类似于以下内容。
在您的父组件中为您 select 的值与此
Autocomplete
创建一个单独的状态。事实上,我根本不会有一个名为AsyncAutocomplete
的单独组件。这样一来,您就可以控制父组件中的所有状态,并且Autocomplete
组件变得纯粹是展示性的。在您的 API 调用完成并调用
类型setOptions(options)
之后,使用您想要显示的值调用setValue
select编辑。这必须是EntityWithIdAndDescription
.为
Autocomplete
组件的onChange
属性创建一个内联函数,该函数将第二个参数作为EntityWithIdAndDescription | null
类型。这是Autocomplete
的onChange
的要求。以此参数为参数调用setValue
。将
options
、value
、onChange
和loading
作为 props 传递到Autocomplete
组件中。除了你在代码中所做的,我已经传递的额外道具是:
<Autocomplete
...
disabled={loading}
value={value}
...
/>
告诉我你过得怎么样
const [value, setValue] = useState<EntityWithIdAndDescription | null>(null); // (1)
const [options, setOptions] = useState<EntityWithIdAndDescription[]>([]);
const loading = options.length === 0;
useEffect(() => {
populateWith().then((options)=> {
setOptions(options);
})
// (2)
setValue({
id: "something",
description: "something",
})
return () => {};
}, []);
// (4)
<Autocomplete
id="async-autocomplete"
disabled={loading}
onChange={(event: any, newValue: EntityWithIdAndDescription | null) => {
setValue(newValue); // (3)
}}
getOptionSelected={(option, value) => option.id === value.id}
getOptionLabel={(option) => option.description}
options={options}
loading={loading}
value={value}
renderInput={(params) => (
<TextField
{...params}
label={"My Entities"}
variant="outlined"
margin="dense"
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</React.Fragment>
),
}}
/>
)}
/>
);
代码沙箱
这是一个在我称为 MyAutocomplete
的单独组件中使用 Autocomplete
的示例。它包括一个 API 调用和设置一个值,我想先 selected。