使用异步数据时,材质UI自动完成功能显示“无选项”

时间:2020-09-08 22:23:23

标签: javascript reactjs autocomplete material-ui

我想点击一个API来填写我的自动填充的options。我使用useEffect进行此操作,可以看到响应中有一个数据数组,但不会显示在“自动完成”中。

enter image description here

如果我将解析的响应硬编码到JS数组中并将其粘贴到initialState对象中,则它将起作用。自动完成功能是否无法检测到状态变化或其他原因?我正在关注this example

enter image description here

没有错误。控制台日志语句显示响应的已分析主体是可用数组。所以我不确定我在做什么错。

响应在被解析之前看起来像这样:

body: "[{"addressList":[{"address":"78 Pine Ave S","city":"Bend","province":"Oregon","postalCode":"89879","country":"USA"},{"address":"998 76 St S","city":"Bend","province":"Oregon","postalCode":"86585","country":"USA"}],"emailList":["adawg@gmail.com","aliyahsamson@yahoo.ca"],"_id":"5f579f50f02ea700316058d7","firstName":"Billy Bob","lastName":"Johnson","alias":"BB-Dawg","__v":0},{"addressList":[],"emailList":[],...

我正在使用的状态以及效果:

const initialState = {
  contacts: [],
};

useEffect(() => {
    let active = true;
    setState({ ...state, loading: true });
    const url = `${environment.api.contacts}/listAll`;

    (async () => {
      await axios.get(url)
        .then((response) => {
          const contacts = JSON.parse(response.data.body);
          console.log('got contacts:', contacts);
          setState({ ...state, contacts });
        })
        .catch((error) => {
          console.error('Error getting contacts:', error);
        })
        .then(() => setState({ ...state, loading: false }));
    })();

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

useEffect(() => {
    if (!state.open) setState({ ...state, contacts: [] });
  }, [state.open]);

这是自动完成

<Autocomplete
              options={state.contacts}
              getOptionLabel={(contact: Contact) => getFullName(contact)}
              onChange={(event: any, contact: any) => { if (contact) handleContactChange(contact) }}
              renderInput={(params) => 
                <TextField
                  {...params}
                  label="Search for a Contact..."
                  variant="outlined"
                  InputProps={{
                    ...params.InputProps,
                    style: {
                      height: 44,
                      padding: '0 14px',
                    },
                    endAdornment: (
                      <InputAdornment position="end">
                        <Search />
                      </InputAdornment>
                    ),
                  }}
                  InputLabelProps={{
                    ...params.InputLabelProps,
                    style: {
                      height: 44,
                      ...({ top: '-6px' }),
                    },
                  }}
                />
              }
            />

1 个答案:

答案 0 :(得分:0)

我使用了一个名为“isLoading”的状态来检查异步调用响应。最初它被设置为 false,一旦我得到响应,我就把它设置为 true。您可以按如下方式向自动完成框添加一些参数。

       <Autocomplete
          loading={isLoading}
          loadingText="Loading..."
          noOptionsText="No Options found"      
          options={state.contacts}
          getOptionLabel={(contact: Contact) => getFullName(contact)}
          onChange={(event: any, contact: any) => { if (contact) handleContactChange(contact) }}
          renderInput={(params) => 
            <TextField
              {...params}
              label="Search for a Contact..."
              variant="outlined"
              InputProps={{
                ...params.InputProps,
                style: {
                  height: 44,
                  padding: '0 14px',
                },
                endAdornment: (
                  <InputAdornment position="end">
                    <Search />
                  </InputAdornment>
                ),
              }}
              InputLabelProps={{
                ...params.InputLabelProps,
                style: {
                  height: 44,
                  ...({ top: '-6px' }),
                },
              }}
            />
          }
        />

从 API 调用获得响应后,将 isLoading 设置为 false。