Я работаю над проектом, для которого я пытаюсь реализовать автозаполнение с помощью предложений во время набора текста: на практике каждая новая набираемая буква соответствует новому запросу к базе данных приложения (которая работает локально).
Технический стек внешнего интерфейса — это React Native, Expo и Redux Toolkit, поэтому я делаю вышеуказанные запросы через RTK Query.
Ниже представлен компонент AddressSearch, отвечающий за:
Flatlist
const AddressSearch = () => {
const styles = stylesFn();
// string from the GUI, grows while typing
const [input, setInput] = useState("");
// string fed to the API, after 2s delay
const [debouncedInput, setDebouncedInput] = useState("");
// raw data as pulled from the API
const [suggestions, setSuggestions] = useState();
// RTKQ skip setting to avoid requesting the API too soon
const [skip, setSkip] = useState(true);
let {
data: rawSuggestions,
isFetching,
isLoading,
isSuccess,
isError,
error,
} = useGetCarQuery(debouncedInput, { skip });
// pass returned `data` to the JSX
useEffect(() => {
if (rawSuggestions) {
setSuggestions(rawSuggestions);
}
}, [rawSuggestions]);
const updateSearchedAddress = (text) => {
text.length > 2 ? setSkip(false) : setSkip(true);
// update the form GUI state
setInput(text);
// update the RTKQ state after 2 seconds
setTimeout(() => {
setDebouncedInput(text);
}, 2000);
};
return (
<View>
{/* ... */}
<FlatList
scrollEnabled = {true}
showVerticalScrollIndicator = {true}
data = {suggestions ? suggestions.results : null}
renderItem = {({ item, index, separators }) => (
<Pressable key = {item.id}>
<Text>
{item.id} {item.make} {item.model} {item.version} {item.fuel}
</Text>
</Pressable>
)}
/>
{/* ... */}
</View>
);
};
export default AddressSearch;
При выполнении поиска можно получить повторяющиеся результаты в соответствии со следующим предупреждением:
Warning: Encountered two children with the same key, `246`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
Насколько я могу судить, вышеизложенное связано с быстрым выполнением нескольких запросов в сочетании с результатами кэширования Redux и отсутствием дедупликации данных.
Итак, я попытался отменить запросы, чтобы не запускать их слишком рано, но я не могу найти эффективный способ сделать это.
Кроме того, я считаю, что форсирование повторных запросов (для полной замены кеша) при каждом нажатии клавиши может решить вышеуказанную проблему, но, будучи новичком в JS, я не уверен, как это сделать.
Отсюда мой вопрос: как мне эффективно избавиться от вышеупомянутого предупреждения, минимизируя запросы и сохраняя логику key
как есть?
Вероятно, вы получаете данные с сервера, который дважды содержит этот ключ. RTK Query по умолчанию не объединяет никаких данных, он всегда заменяет старые данные, так что этого быть не может.
Кроме того, вам действительно не нужно это useEffect
там. Просто работайте напрямую с data/rawSuggestions
. Ваш useEffect
просто добавляет еще один ререндер. Если вы хотите получить данные из этого, используйте вместо этого useMemo
.
дорогая @phry, спасибо за обе подсказки!