问题描述
我有这个屏幕 [![Screen][1]][1],我可以在其中搜索带有自动建议的企业(由谷歌地图 placeAutoComplete 提供)。如果用户在 placeAutoComplete 未建议的文本上键入 Enter,则服务器会选择地图 textSearch 选项并在地图上显示结果。
现在我的问题是,当用户点击地图上的地点时,我希望该地点的名称显示在自动建议中。
我正在努力弄清楚如何仅在选择值(从外部事件)时绑定该值
当然,我尝试设置该值(只要没有选择,就将其设为 null):我收到此错误
VM11047 react_devtools_backend.js:2560 Material-UI: A component is changing the uncontrolled value state of Autocomplete to be controlled.
Elements should not switch from uncontrolled to controlled (or vice versa).
Decide between using a controlled or uncontrolled Autocomplete element for the lifetime of the component.
The nature of the state is determined during the first render,it's considered controlled if the value is not `undefined`.
EntityAutocomplete.js
import React,{useState} from 'react';
import TextField from '@material-ui/core/TextField';
import Autocomplete from '@material-ui/lab/Autocomplete';
import {useTranslation} from "next-i18next";
import {useRouter} from "next/router";
import {REGION_LIST,PLACE_CANDIDATE_LIST} from "../../../constants/graphQueries";
import {useQuery} from "@apollo/client";
import logger from "../../../lib/logger";
import {defaultIfNull} from "../../../constants/util";
export default function EntityAutocomplete(props) {
const [value,setValue] = useState();
const [searchText,setSearchText] = useState([]);
const [options,setoptions] = useState([]);
const [loadingTextSearch,setLoadingTextSearch] = useState(true);
const {t} = useTranslation()
const router = useRouter()
const isSearchEmpty = searchText.length == 0 || searchText.trim().length == 0;
const {loading,data,error} = useQuery(REGION_LIST,{
variables: {name: searchText},onCompleted: onServerResponse,skip: isSearchEmpty
})
// triggered if a text was entered manually (not from list)
const {loadingMarkers,markersData,markerSearchError} = useQuery(PLACE_CANDIDATE_LIST,onCompleted: onTextSearchResponse,skip: !loadingTextSearch,fetchPolicy: "no-cache",notifyOnNetworkStatusChange: true
})
// disable trigger just after executing the request
if (loading) {
// logger.debug("loading")
}
if (error) {
logger.info("error: ",error)
}
function onServerResponse(data) {
if (data) {
setoptions(data.locationMany);
}
}
function onTextSearchResponse(data) {
const {onMarkersChanged} = props
if (data) {
const locationCandidateMany = data.locationCandidateMany;
if (onMarkersChanged)
onMarkersChanged(locationCandidateMany)
//must be placed here otherwise this callback is not called if disabled before response
if (loadingTextSearch)
setLoadingTextSearch(false)
}
}
function valueChanged(event,newValue) {
setValue(newValue);
const onEntitySelected = props.onEntitySelected;
if (isAutoSuggestion(newValue)) {
if (onEntitySelected != null)
onEntitySelected(value)
return
}
//text was typed with enter: find matching results
setLoadingTextSearch(true)
}
function isAutoSuggestion(option) {
return option?.source != null;
}
function getoptionLabel(option) {
return isAutoSuggestion(option) ? option.name : option;
}
return (
<Autocomplete
value={props.selected}
freeSolo
onChange={valueChanged}
onInputChange={(e,value) => {
setSearchText(value)
}}
options={options}
getoptionLabel={getoptionLabel}
disableClearable
renderInput={(params) => (
<TextField
{...params}
label={t(`service.search.placeholder`)}
margin="normal"
variant="outlined"
InputProps={{...params.InputProps,type: 'search'}}
/>
)}
/>
);
}
父组件这样调用它:
<Grid item className={classes.entitySelector}>
<EntityAutocomplete label={t(`common.entityHome.selectEntity.entityLabel`)}
entityName={issue.entity?.name} onEntitySelected={onPlaceSelected}
onSelectedEntityInfoLoaded={onSelectedEntityInfoLoaded}
onMarkersChanged={setMarkers} selected={selectedplace}/>
</Grid>
我还尝试添加一种效果,如果 select
不为空,则仅保留一个选项可用:
const {selected} = props useEffect(() => { 如果(选择!= null){ 设置选项([选择]) } },[已选])
但它不起作用 [1]:https://i.stack.imgur.com/t3dhG.png
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)