当数据可用时,MaterialUI 组件不会自动完成

Dea*_*ean 6 javascript typescript reactjs material-ui

我无法让我的组件显示我的自动建议。在控制台中观察到我的数据可用,我使用建议道具将其发送到该组件,使用 Material UI AutoComplete 组件功能在这里我尝试设置我的选项,这些在我输入时发生变化,因为它在一个父组件,但设置值似乎没有反映也没有提出我的建议。我很困扰。我的代码在下面。

import React, { FunctionComponent, FormEvent, ChangeEvent } from "react";
import { Grid, TextField, Typography } from "@material-ui/core";
import { CreateProjectModel, JobModel } from "~/Models/Projects";
import ErrorModel from "~/Models/ErrorModel";
import Autocomplete from "@material-ui/lab/Autocomplete";

type CreateProjectFormProps = {
    model: CreateProjectModel;
    errors: ErrorModel<CreateProjectModel>;
    onChange: (changes: Partial<CreateProjectModel>) => void;
    onSubmit?: () => Promise<void>;
    suggestions: JobModel[];
};

const CreateProjectForm: FunctionComponent<CreateProjectFormProps> = ({
    model,
    errors,
    onChange,
    onSubmit,
    suggestions,
}) => {
    const [open, setOpen] = React.useState(false);
    const [options, setOptions] = React.useState<JobModel[]>([]);
    const loading = open && options.length === 0;
    const [inputValue, setInputValue] = React.useState('');
    React.useEffect(() => {
        let active = true;

        if (!loading) {
            return undefined;
        }

        (async () => {
            if (active) {
                setOptions(suggestions);
            }
        })();

        return () => {
            active = false;
        };
    }, [loading]);

    React.useEffect(() => {
        if (!open) {
            setOptions([]);
        }
    }, [open]);

    const submit = async (event: FormEvent) => {
        event.preventDefault();
        event.stopPropagation();

        await onSubmit();
    };

    const change = (name: string) => (event: ChangeEvent<HTMLInputElement>) => {
        setInputValue(event.target.value);

        onChange({
            [name]: event.target.value,
        });
    };

    const getFieldProps = (id: string, label: string) => {
        return {
            id,
            label,
            helperText: errors[id],
            error: Boolean(errors[id]),
            value: model[id],
            onChange: change(id),
        };
    };

    return (
        <Autocomplete
            {...getFieldProps}
            open={open}
            onOpen={() => {
                setOpen(true);
            }}
            onClose={() => {
                setOpen(false);
            }}
            getOptionSelected={(option, value) => option.id === value.id}
            getOptionLabel={(option) => option.id}
            options={options}
            loading={loading}
            autoComplete
            includeInputInList            
            renderInput={(params) => (
                <TextField
                    {...getFieldProps("jobNumber", "Job number")}
                    required
                    fullWidth
                    autoFocus
                    margin="normal"
                />
            )}
            renderOption={(option) => {        
                return (
                  <Grid container alignItems="center">

                    <Grid item xs>
                      {options.map((part, index) => (
                        <span key={index}>
                          {part.id}
                        </span>
                      ))}
                      <Typography variant="body2" color="textSecondary">
                        {option.name}
                      </Typography>
                    </Grid>
                  </Grid>
                );
              }}            
        />
    );
};

export default CreateProjectForm;
Run Code Online (Sandbox Code Playgroud)

我在建议中的数据示例如下所示:

[{"id":"BR00001","name":"Aircrew - Standby at home base"},{"id":"BR00695","name":"National Waste"},{"id":"BR00777B","name":"Airly Monitor Site 2018"},{"id":"BR00852A","name":"Cracow Mine"},{"id":"BR00972","name":"Toowoomba Updated"},{"id":"BR01023A","name":"TMRGT Mackay Bee Creek"},{"id":"BR01081","name":"Newman Pilot Job (WA)"},{"id":"BR01147","name":"Lake Vermont Monthly 2019"},{"id":"BR01158","name":"Callide Mine Monthly Survey 2019"},{"id":"BR01182","name":"Lake Vermont Quarterly 2019 April"}]
Run Code Online (Sandbox Code Playgroud)

小智 1

我注意到您的代码存在一些问题,getFieldProps在没有 id 或名称参数的情况下调用会导致页面无法加载。更重要的是,在传递和使用 props 时,您应该考虑遵循自动完成文档。例如:

renderInput={(params) => <TextField {...params} label="Controllable" variant="outlined" />}
Run Code Online (Sandbox Code Playgroud)

我问了几个问题,请告诉我您何时可以获得这些答案,以便我可以解决可能出现的所有问题。

Q1. 用户输入应该提供建议中 name 属性的相关匹配项还是仅提供 id?对于前。如果我输入“lake”,您是否想将 BRO1182,Lake Vermont Quarterly 2019 April 作为匹配项显示?

Q2。您想如何解决错误情况?我看到您有一个错误模型,但不确定发生错误时您希望如何使用它来设置自动完成的样式

Q3。我们缺少提交按钮吗?我看到了这个onSubmit函数,但我们的代码中没有使用它。

Q4。您需要打开和加载状态是否有特殊原因?

以下是迄今为止我尝试显示用户输入的相关匹配项

import React, { FunctionComponent, FormEvent, ChangeEvent } from "react";
import { Grid, TextField, Typography } from "@material-ui/core";
import { CreateProjectModel, JobModel } from "~/Models/Projects";
import ErrorModel from "~/Models/ErrorModel";
import Autocomplete from "@material-ui/lab/Autocomplete";

type CreateProjectFormProps = {
  model: CreateProjectModel;
  errors: ErrorModel<CreateProjectModel>;
  onChange: (changes: Partial<CreateProjectModel>) => void;
  onSubmit?: () => Promise<void>;
  suggestions: JobModel[];
};

const CreateProjectForm: FunctionComponent<CreateProjectFormProps> = ({
  model,
  errors,
  // mock function for testing
  // consider a better name like selectChangeHandler
  onChange = val => console.log(val),
  // consider a better name like submitJobFormHandler
  onSubmit,
  suggestions: options = [
    { id: "BR00001", name: "Aircrew - Standby at home base" },
    { id: "BR00695", name: "National Waste" },
    { id: "BR00777B", name: "Airly Monitor Site 2018" },
    { id: "BR00852A", name: "Cracow Mine" },
    { id: "BR00972", name: "Toowoomba Updated" },
    { id: "BR01023A", name: "TMRGT Mackay Bee Creek" },
    { id: "BR01081", name: "Newman Pilot Job (WA)" },
    { id: "BR01147", name: "Lake Vermont Monthly 2019" },
    { id: "BR01158", name: "Callide Mine Monthly Survey 2019" },
    { id: "BR01182", name: "Lake Vermont Quarterly 2019 April" }
  ]
}) => {
  const [value, setValue] = React.useState<JobModel>({});
  const loading = open && options.length === 0;

  // this pc of code is not used, why?
  const submit = async (event: FormEvent) => {
    event.preventDefault();
    event.stopPropagation();

    await onSubmit();
  };

  const handleChange = (_: any, value: JobModel | null) => {
    setValue(value);

    onChange({
      [value.name]: value.id
    });
  };

  // consider passing in props instead
  const getFieldProps = (id: string, label: string) => {
    return {
      id,
      label,
      // not sure what this is
      helperText: errors[id],
      // not sure what this is
      error: Boolean(errors[id]),
      value: model[id],
      onChange: change(id)
    };
  };

  return (
    <Autocomplete
      id="placeholder-autocomplete-input-id"
      // for selection, use value see docs for more detail
      value={value}
      onChange={handleChange}
      getOptionSelected={(option, value) => option.id === value.id}
      getOptionLabel={option => option.id}
      options={options}
      loading={loading}
      autoComplete
      includeInputInList
      renderInput={params => (
        // spreading the params here will transfer native input attributes from autocomplete
        <TextField
          {...params}
          label="placeholder"
          required
          fullWidth
          autoFocus
          margin="normal"
        />
      )}
      renderOption={option => (
        <Grid container alignItems="center">
          <Grid item xs>
            <span key={option}>{option.id}</span>
            <Typography variant="body2" color="textSecondary">
              {option.name}
            </Typography>
          </Grid>
        </Grid>
      )}
    />
  );
};

export default CreateProjectForm;
Run Code Online (Sandbox Code Playgroud)

您可以通过单击下面的按钮查看我的codesandbox中运行的代码

编辑锐牛顿-87eng