我正在尝试将material-ui useAutocomplete
与异步调用一起使用。
使用autocomplete
很简单,但是我需要调整输入焦点时显示的对话框,因此我必须使用useAutocomplete
。
所以我尝试合并此代码(异步):https://codesandbox.io/s/pvjgx
与此(useAutocomplete):https://codesandbox.io/s/261pd?file=/demo.js
问题是我不知道在哪里或如何将onChange
放入输入中,因此我可以触发获取数据的异步函数
这是我到目前为止得到的无效代码(无效的沙箱)https://codesandbox.io/s/material-demo-gl9pw?file=/demo.js
import React from "react";
import useAutocomplete from "@material-ui/lab/useAutocomplete";
import { InputBase } from "@material-ui/core";
import CircularProgress from "@material-ui/core/CircularProgress";
import styled from "styled-components";
import { makeStyles } from "@material-ui/core/styles";
const Listbox = styled("ul")`
width: 300px; margin: 2px 0 0;padding: 0;position: absolute; list-style: none; background-color: #fff;overflow: auto;max-height: 250px; border-radius: 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); z-index: 1;
& li {padding: 5px 12px; display: flex; & span {flex-grow: 1; }& svg { color: transparent; } }
& li[aria-selected="true"] { background-color: #fafafa; font-weight: 600; & svg {color: #1890ff;}}
& li[data-focus="true"] {background-color: #e6f7ff; cursor: pointer; & svg { color: #000; } }
`;
const useStyles = makeStyles(theme => ({
autoWidth: {width: "auto"},
input: {
marginLeft: theme.spacing(1),
flex: 1,
color: "white",
textAlign: "center",
align: "center",
"& input": {
textAlign: "center"
}
},
iconButton: {
padding: 10,
color: "white"
},
searchRoot: {
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: "blue"
}
}));
export default function MyAutocomplete() {
const classes = useStyles();
const [value, setValue] = React.useState("");
const [open, setOpen] = React.useState(false);
const [options, setOptions] = React.useState([]);
const loading = open && options.length === 0;
React.useEffect(() => {
let active = true;
if (!loading) { return undefined; }
console.log("run")(async () => {
const response = await fetch("https://country.register.gov.uk/records.json?page-size=5000");
const countries = await response.json();
if (active) {
setOptions(Object.keys(countries).map(key => countries[key].item[0]));
}
})();
return () => {
active = false;
};
}, [loading]);
React.useEffect(() => {
if (!open) {
setOptions([]);
}
}, [open]);
const {
getRootProps, getInputLabelProps, getInputProps, getListboxProps, getOptionProps, groupedOptions, focused, setAnchorEl
// value
} = useAutocomplete({
id: "customized-autocomplete-async",
options: options,
getOptionLabel: option => option.name
});
return (
<div className={classes.autoWidth}>
<div {...getRootProps()}>
<InputBase
{...getInputProps()}
//value={value}
//onChange={event => {setValue(event.target.value); }}
inputRef={setAnchorEl}
className={classes.input}
placeholder="Localisation"
inputProps={{ "aria-label": "Localisation" }}
fullWidth={true}
endAdornment={
<React.Fragment>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
</React.Fragment>
}
/>
</div>
{focused && (
<div className={classes.autoWidth}>
<Listbox {...getListboxProps()}>
<div> Localiser moi ! </div>
<br />
{groupedOptions.map((option, index) => (
<li {...getOptionProps({ option, index })}>
<span>{option.title}</span>
</li>
))}
</Listbox>
</div>
)}
</div>
);
}
欢迎任何提示
答案 0 :(得分:0)
您在问题中复制了两次相同的链接,所以我真的不知道您想要实现什么。 我正在将自动完成功能与TextField输入配合使用:
<Autocomplete
options={ isValidating ? [{nickname: '...loading'}] : data ? data : [] }
getOptionLabel={(option) => option.nickname}
id="auto-complete"
autoComplete
includeInputInList
value={value}
onChange={(event, newValue) => {
setValue(newValue);
}}
onInputChange={(event, newInputValue) => {
console.log(newInputValue);
}}
renderInput={(params) => <TextField {...params} error={error} helperText={error} label="Email Address or User ID" value={query} onChange={handleChange} margin="normal" />}
/>
并使用Swr提取数据:
const [query, setQuery] = React.useState('');
const [value, setValue] = React.useState()
const [loading, setLoading] = React.useState(false)
const { data, isValidating } = useSwr(active && query.length > 2 ? '/api/getusers?q='+query : '', fetcher)
const handleChange = (event) => {
setQuery(event.target.value);
};
一切都异步运行。
也许可以尝试进一步澄清您的问题,以便我改善回答:)