Почему инпут селекта из react-select не сразу отображает inputValue?
Всем привет. У меня есть форма, в которой связаны карта, координаты и вся остальная форма вместе с полем formatted, которое с автодополнением. Логика всей формы завязана на координатах:
- выбираем на карте точку, берутся ее координаты, вставляются значения в
lat, lng;
ИЛИ
- вводим координаты;
ИЛИ
- начинаем вводить адрес и выбираем из автодополнения.
После того, как получили координаты одним из трех способов мы при помощи googlemaps-api и этих самых координат получаем все данные и вставляем значения в форму. В третьем случае получается так, что мы вводим в поле formatted значение, по нему находим координаты, по этим координатам получаем адрес и заново перезаписываем это поле, по сути, тем же значением. Но не понятно, почему, например, первый вариант(с картой) работает нормально и все сразу отображается, а в третьем варианте оно сетается, но, почему-то, отображается не сразу.
Видео с демонстрацией
import { RefAttributes, useCallback, useEffect, useState } from 'react'
import { InputSelect, SelectOption } from '@widgets/ui/Select'
import { useAddressPredictions } from '@shared/ui/Map/useAddressPredictions.ts'
import { addressPredictionToOptions, isEmpty } from '@shared/ui/Map/utils.ts'
import { StateManagerProps } from 'react-select/dist/declarations/src/stateManager'
import { useAddress } from '@shared/ui/Map/useAddress.ts'
import { PlaceId } from '@shared/ui/Map/types.ts'
import { Coords } from 'google-map-react'
import { GroupBase, InputActionMeta } from 'react-select/dist/declarations/src/types'
import Select from 'react-select/dist/declarations/src/Select'
interface AddressAutocompleteProps {
onSelect: (coords: Coords) => void
}
const AddressAutocomplete = <
Option = unknown,
IsMulti extends boolean = false,
Group extends GroupBase<Option> = GroupBase<Option>,
>({
inputValue,
onInputChange,
onSelect,
...props
}: StateManagerProps<Option, IsMulti, Group> &
RefAttributes<Select<Option, IsMulti, Group>> &
AddressAutocompleteProps) => {
const [options, setOptions] = useState<SelectOption<PlaceId>[] | null>(null)
const fetchAddressPredictions = useAddressPredictions(inputValue)
const { getCoordsByPlaceId } = useAddress()
const handleSelect = useCallback(
async (v: SelectOption<PlaceId>) => {
const coords = await getCoordsByPlaceId(v.value)
onSelect(coords)
},
[getCoordsByPlaceId, onSelect],
)
const handleFetchPredictionsOptions = useCallback(
async (v: string) => {
const res = await fetchAddressPredictions(v)
setOptions(addressPredictionToOptions(res.predictions))
},
[fetchAddressPredictions],
)
const handleInputValueChange = useCallback(
async (v: string, actionMeta: InputActionMeta) => {
console.log(actionMeta.action)
if (actionMeta.action !== 'input-change') return
onInputChange(v, actionMeta)
if (!isEmpty(v)) {
await handleFetchPredictionsOptions(v)
}
},
[handleFetchPredictionsOptions, onInputChange],
)
return (
<InputSelect
placeholder={'Start enter address'}
{...props}
options={options ?? undefined}
onChange={handleSelect}
inputValue={inputValue}
onInputChange={handleInputValueChange}
components={{ DropdownIndicator: null }}
filterOption={option => option} // we don`t need to filter options
/>
)
}
export default AddressAutocomplete
В форме(react-hook-form) я использую так:
<FormField
control={control}
name='formatted'
render={({ field }) => (
<FormItem className={'w-full'}>
<FormLabel>Formatted</FormLabel>
<FormControl>
<AddressAutocomplete
name={field.name}
ref={field.ref}
onBlur={field.onBlur}
inputValue={field.value}
onInputChange={v => field.onChange(v)}
onSelect={setCoords}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>