首页 > 解决方案 > 在 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 似乎不起作用。任何有关修改此内容或采取不同方法的建议都会有所帮助。

标签: reactjsmaterial-uifrontendreact-typescript

解决方案


看起来您所追求的是受控组件在 Playground 下 Material UI 的 Autocomplete 演示中有一个这样的示例,称为受控。

我不确定您如何获得id要传递给组件以表明它已被选中的初始值。它可能类似于以下内容。

  1. Autocomplete为您在父组件中选择的值创建一个单独的状态。事实上,我根本不会调用单独的组件AsyncAutocomplete。这样您就可以控制父组件中的所有状态,并且该Autocomplete组件变得纯粹是展示性的。

  2. 在您的 API 调用完成并被setOptions(options)调用后,setValue使用您希望显示为选中的值进行调用。这必须是类型EntityWithIdAndDescription

  3. onChange为组件的prop创建一个内联函数,该函数Autocomplete将第二个参数作为EntityWithIdAndDescription | null类型。这是Autocomplete's所要求的onChangesetValue使用此参数作为参数调用。

  4. options将, value,onChangeloadingas传递给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 调用和设置一个我想首先被选中的值。

https://codesandbox.io/s/autumn-silence-lkjrf


推荐阅读