【问题标题】:Trigger completeMethod in PrimeReact Autocomplete on callback在回调时触发 PrimeReact Autocomplete 中的 completeMethod
【发布时间】:2025-12-15 12:25:02
【问题描述】:

我正在使用 primereact 的自动完成组件。挑战在于我不想将选项数组设置为组件加载时的状态;但是当用户输入前 3 个字母时,我会触发 api 调用,然后将响应设置为选项数组(这是因为否则数组可能很大,我不想膨胀状态内存)。

const OriginAutocomplete = () => {

    const [origins, setOrigins] = useState([]);
    const [selectedOrigin, setSelectedOrigin] = useState(null);
    const [filteredOrigins, setFilteredOrigins] = useState([]);

    useEffect(() => {
        if (!selectedOrigin || selectedOrigin.length < 3) {
            setOrigins([]);
        }
        if (selectedOrigin && selectedOrigin.length === 3) {
            getOrigins(selectedOrigin).then(origins => {
                setOrigins([...origins]);
            });
        }
    }, [selectedOrigin, setOrigins]);

    const handleSelect = (e) => {
        //update store
    }

    const searchOrigin = (e) => {
        //filter logic based on e.query
    }

    return (
        <>
            <AutoComplete
                value={selectedOrigin}
                suggestions={ filteredOrigins }
                completeMethod={searchOrigin}
                field='code'
                onChange={(e) => { setSelectedOrigin(e.value) }}
                onSelect={(e) => { handleSelect(e) }}
                className={'form-control'}
                placeholder={'Origin'}
            />
        </>
    )
}

现在的问题是当我输入 3 个字母时会触发呼叫,但只有当我输入第 4 个字母时才会列出选项。 没关系,事实上我尝试更改代码以在我输入 2 个字母时触发呼叫;但是只有当我在 api 调用完成后键入第 3 个字母时才能按预期工作,即,我键入 2 个字母,等待调用完成,然后键入第 3 个字母。

如何在选项数组发生变化时显示选项?

我尝试在回调中设置过滤的Origins


            getOrigins(selectedOrigin).then(origins => {
                setOrigins([...origins]);
                setFilteredOrigins([...origins])
            });

但它似乎不起作用。

【问题讨论】:

    标签: reactjs primereact


    【解决方案1】:

    想通了。发布答案以防有人思考同样的问题。 我将useEffect 中的代码移到searchOrigin 函数中。

    所以 searchOrigin 函数如下所示:

        const searchOrigin = (e) => {
            const selectedOrigin = e.query;
            
            if (!selectedOrigin || selectedOrigin.length === 2) {
                         setOrigins([]);
                         setFilteredOrigins([]);
            }
            
            if (selectedOrigin && selectedOrigin.length === 3) {
                getOrigins(selectedOrigin).then(origins => {
                    setOrigins([...origins]);
                    setFilteredOrigins(origins);
                });
            }       
    
            if (selectedOrigin && selectedOrigin.length > 3) {
                    const filteredOrigins = (origins && origins.length) ? origins.filter((origin) => {
                        return origin.code
                            .toLowerCase()
                            .startsWith(e.query.toLowerCase()) || 
                            origin.name
                            .toLowerCase()
                            .startsWith(e.query.toLowerCase())  ||
                            origin.city
                            .toLowerCase()
                            .startsWith(e.query.toLowerCase())
                  }) : [];
                  setFilteredOrigins(filteredOrigins);
            }
        }
    

    【讨论】: