У меня есть следующий компонент, адрес которого вы предлагаете мне.
Проблема в том, что мне нужны адреса, которые вы мне предлагаете, для ссылки на одно состояние.
Есть ли способ указать это ограничение через API?
Или, по вашему мнению, есть способ, который я мог бы сделать с помощью кода?
Я думал, что что-то делаю внутри, вы хотите, чтобы он думал, что это правильный путь? Могут ли у меня проблемы?
React.useEffect(() => {
let active = true;
if (!autocompleteService.current && window.google)
autocompleteService.current = new window.google.maps.places.AutocompleteService();
if (!autocompleteService.current) return undefined;
if (value === '') {
setOptions([]);
return undefined;
}
fetch({ input: value }, res => {
//edit
const loc = res.map(a => (a.description.split(',').pop().trim() === 'Italia' ? a : false)).filter(Boolean);
if (active) setOptions(loc || []);
});
return () => {
active = false;
};
}, [value, fetch]);
Код:
import React from 'react';
import { useTranslation } from 'react-i18next';
import { makeStyles, TextField, Grid, Typography } from '@material-ui/core';
import { Autocomplete } from '@material-ui/lab';
import { LocationOn } from '@material-ui/icons';
import parse from 'autosuggest-highlight/parse';
import throttle from 'lodash/throttle';
function loadScript(src, position, id) {
if (!position) return;
const script = document.createElement('script');
script.setAttribute('async', '');
script.setAttribute('id', id);
script.src = src;
position.appendChild(script);
}
const autocompleteService = { current: null };
const useStyles = makeStyles(theme => ({
icon: {
color: theme.palette.text.secondary,
marginRight: theme.spacing(2)
}
}));
export default function AutocompleteGoogleMaps(props) {
const { api, value, onChange, changeinfo } = props;
const classes = useStyles();
const [options, setOptions] = React.useState([]);
const loaded = React.useRef(false);
const { i18n } = useTranslation();
let language = localStorage.getItem('lang');
if (language === null) language = i18n.language;
if (typeof window !== 'undefined' && !loaded.current) {
if (!document.querySelector('#google-maps')) {
loadScript(
`https://maps.googleapis.com/maps/api/js?key=${api}&libraries=places&language=${language}`,
document.querySelector('head'),
'google-maps'
);
}
loaded.current = true;
}
const handleChange = ({ target: { value } }) => {
onChange(value);
};
const onTagsChange = (event, val) => {
if (val !== null && val.description !== null) {
onChange({ target: { value: val.description } });
if (changeinfo) geocodeByAddress(val.description).then(changeinfo);
}
};
const fetch = React.useMemo(
() =>
throttle((input, callback) => {
autocompleteService.current.getPlacePredictions(input, callback);
}, 200),
[]
);
React.useEffect(() => {
let active = true;
if (!autocompleteService.current && window.google)
autocompleteService.current = new window.google.maps.places.AutocompleteService();
if (!autocompleteService.current) return undefined;
if (value === '') {
setOptions([]);
return undefined;
}
fetch({ input: value }, res => {
if (active) setOptions(res || []);
});
return () => {
active = false;
};
}, [value, fetch]);
const geocodeByAddress = address => {
const geocoder = new window.google.maps.Geocoder();
const { OK } = window.google.maps.GeocoderStatus;
return new Promise((resolve, reject) => {
geocoder.geocode({ address }, (results, status) => {
if (status !== OK) {
return reject(status);
}
return resolve(results);
});
});
};
return (
<Autocomplete
id="google-map"
getOptionLabel={option => (typeof option === 'string' ? option : option.description)}
filterOptions={x => x}
options={options}
autoComplete
includeInputInList
freeSolo
value={value}
renderInput={params => <TextField {...params} onChange={handleChange} {...props} />}
onChange={onTagsChange}
renderOption={({
structured_formatting: {
main_text_matched_substrings: matches,
main_text: city,
secondary_text: street
}
}) => {
const parts = parse(
city,
matches.map(match => [match.offset, match.offset + match.length])
);
return (
<Grid container alignItems="center">
<Grid item>
<LocationOn className={classes.icon} />
</Grid>
<Grid item xs>
{parts.map(({ highlight, text }, key) => (
<span key={key} style={{ fontWeight: highlight ? 700 : 400 }}>
{text}
</span>
))}
<Typography variant="body2" color="textSecondary">
{street}
</Typography>
</Grid>
</Grid>
);
}}
/>
);
}