reactjs - 在 Material UI 自动完成上显示一个值(而不是标签)
问题描述
所以我有一个异步组合框,可以从 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 似乎不起作用。任何有关修改此内容或采取不同方法的建议都会有所帮助。
解决方案
看起来您所追求的是受控组件。在 Playground 下 Material UI 的 Autocomplete 演示中有一个这样的示例,称为受控。
我不确定您如何获得id
要传递给组件以表明它已被选中的初始值。它可能类似于以下内容。
Autocomplete
为您在父组件中选择的值创建一个单独的状态。事实上,我根本不会调用单独的组件AsyncAutocomplete
。这样您就可以控制父组件中的所有状态,并且该Autocomplete
组件变得纯粹是展示性的。在您的 API 调用完成并被
setOptions(options)
调用后,setValue
使用您希望显示为选中的值进行调用。这必须是类型EntityWithIdAndDescription
。onChange
为组件的prop创建一个内联函数,该函数Autocomplete
将第二个参数作为EntityWithIdAndDescription | null
类型。这是Autocomplete
's所要求的onChange
。setValue
使用此参数作为参数调用。options
将,value
,onChange
和loading
as传递给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>
),
}}
/>
)}
/>
);
代码沙箱
Autocomplete
这是我调用的单独组件中的示例MyAutocomplete
。它包括一个 API 调用和设置一个我想首先被选中的值。
推荐阅读
- javascript - 欧拉计划 #29:为什么我的答案是 37?
- ansible - 如何解决 ansible win_hotfix 模块的问题
- azure - 对象中缺少必需的属性:qnaRuntimeEndpoint
- java - 由于“org.hibernate.internal.SessionFactoryImpl”检测到内存泄漏
- java - 在日历 SWT 中为日期设置一些条件
- c# - IEnumerable
比较 - javascript - 混合内容:“https://example.com/sw.js”处的页面是通过 HTTPS 加载的,但请求了不安全的资源“http://example.com/about/”
- r - 我可以从函数参数创建值名称,并为其分配函数输出吗?
- django - 如何在 django 模型中打印字段的字段类型
- node.js - 转换为数值失败 - GraphQL