微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 React 自动完成设置事件值

如何解决如何使用 React 自动完成设置事件值

我有这个屏幕 [![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 举报,一经查实,本站将立刻删除。