--- order: 12 title: zh-CN: 搜索用户 en-US: Search and Select Users --- ## zh-CN 一个带有远程搜索,防抖控制,请求时序控制,加载状态的多选示例。 ## en-US A complete multiple select sample with remote search, debounce fetch, ajax callback order flow, and loading state. ```tsx import React, { useState, useRef, useMemo } from 'react'; import { Select, Spin } from 'antd'; import type { SelectProps } from 'antd/es/select'; import debounce from 'lodash/debounce'; export interface DebounceSelectProps extends Omit, 'options' | 'children'> { fetchOptions: (search: string) => Promise; debounceTimeout?: number; } function DebounceSelect< ValueType extends { key?: string; label: React.ReactNode; value: string | number } = any, >({ fetchOptions, debounceTimeout = 800, ...props }: DebounceSelectProps) { const [fetching, setFetching] = useState(false); const [options, setOptions] = useState([]); const fetchRef = useRef(0); const debounceFetcher = useMemo(() => { const loadOptions = (value: string) => { fetchRef.current += 1; const fetchId = fetchRef.current; setOptions([]); setFetching(true); fetchOptions(value).then(newOptions => { if (fetchId !== fetchRef.current) { // for fetch callback order return; } setOptions(newOptions); setFetching(false); }); }; return debounce(loadOptions, debounceTimeout); }, [fetchOptions, debounceTimeout]); return ( labelInValue filterOption={false} onSearch={debounceFetcher} notFoundContent={fetching ? : null} {...props} options={options} /> ); } // Usage of DebounceSelect interface UserValue { label: string; value: string; } async function fetchUserList(username: string): Promise { console.log('fetching user', username); return fetch('https://randomuser.me/api/?results=5') .then(response => response.json()) .then(body => body.results.map( (user: { name: { first: string; last: string }; login: { username: string } }) => ({ label: `${user.name.first} ${user.name.last}`, value: user.login.username, }), ), ); } const App: React.FC = () => { const [value, setValue] = useState([]); return ( { setValue(newValue); }} style={{ width: '100%' }} /> ); }; export default App; ```