Почему React отображает промежуточное состояние между двумя вызовами setState? [дублированная вопрос]
Почему React отображает промежуточное состояние между вызовами setState? ## Введение В процессе разработки пользовательского интерфейса часто возникают ситуации, когда неожиданные промежуточные состояния могут появляться между вызовами `setState` в React....
![Почему React отображает промежуточное состояние между двумя вызовами setState? [дублированная вопрос]](https://api.andrey-dev.online/wp-content/uploads/2026/09/img-43de20e9-1788582319.jpg)
![Почему React отображает промежуточное состояние между двумя вызовами setState? [дублированная вопрос] - image 2](https://api.andrey-dev.online/wp-content/uploads/2026/09/img-d6c5a487-1788582330.jpg)
Почему React отображает промежуточное состояние между вызовами setState?
Введение
В процессе разработки пользовательского интерфейса часто возникают ситуации, когда неожиданные промежуточные состояния могут появляться между вызовами setState в React. Это может быть особенно заметно на страницах, где пользователь выполняет несколько действий подряд. В данной статье рассмотрим пример из реальной разработки, связанной с поиском адреса и отображением результатов.
Пример реализации
Рассмотрим страницу AddressSearch, которая позволяет пользователю вводить адрес, получать предложенные варианты от Google Maps API и отображать результаты на экране. Важные части кода представлены ниже:
export const useSystemAddressStrategy = ({ companyId, gMaps, initialAddress }: SystemAddressStrategyOptions): StrategyResult => {
// ----- Address
const [addressParams, setAddressParams] = useState<AdvancedSearchAddressPayload & { formattedAddress: string }>(convertToAddressPayload(initialAddress));
// ----- Page
const [page, setPage] = useState<number>(0);
// ----- Sort Direction
const [sortDirection, setSortDirection] = useState<SortDirection>(SortDirection.ASC);
};
Основные действия
- Изменение адреса: При изменении адреса все данные на UI очищаются, происходит новый запрос с новым адресом, и данные отображаются.
- Изменение сортировки: При изменении направления сортировки все данные на UI также очищаются, происходит новый запрос с новым направлением сортировки, и данные отображаются.
- Прокрутка до конца страницы: При прокрутке до конца страницы происходит вызов нового API-запроса с увеличенным номером страницы, и новые данные добавляются к существующим.
Проблема промежуточного состояния
Проблема заключается в том, что между вызовами setState может появляться промежуточное состояние, которое не соответствует ни одному из ожидаемых состояний. Это происходит из-за асинхронности вызовов API и обновления состояния компонента.
Как это работает
Когда пользователь выполняет действие, например, меняет адрес, React обновляет состояние и рендерит компонент. Однако, до тех пор, пока новый запрос API не завершится и не обновит состояние, промежуточное состояние может быть видно на экране.
Пример
Предположим, пользователь вводит новый адрес. React обновляет состояние и рендерит компонент с очищенным UI. После этого происходит API-запрос. До завершения запроса, пользователь может видеть промежуточное состояние, где часть данных уже обновилась, а часть еще нет.
Решение проблемы
Чтобы избежать промежуточного состояния, можно использовать различные подходы:
1. Использование флагов загрузки
Добавьте флаг загрузки для каждого действия, чтобы отображать состояние загрузки вместо промежуточного состояния.
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (isLoading) {
return;
}
setIsLoading(true);
fetchNewData()
.then(data => {
// Обновление состояния после получения данных
setPage(0);
setAddressParams(convertToAddressPayload(newAddress));
})
.finally(() => setIsLoading(false));
}, [isLoading, newAddress]);
2. Заморозка UI
Заморозьте UI во время выполнения запроса и разморозьте его после получения данных.
const handleAddressChange = (newAddress) => {
setIsLoading(true);
fetchNewData(newAddress)
.then(data => {
setPage(0);
setAddressParams(convertToAddressPayload(newAddress));
})
.finally(() => setIsLoading(false));
};
3. Управление состоянием внутри функций
Используйте функциональные методы для управления состоянием внутри обработчиков событий.
const handleAddressChange = (newAddress) => {
const fetchData = async () => {
setIsLoading(true);
await fetchNewData(newAddress);
setPage(0);
setAddressParams(convertToAddressPayload(newAddress));
setIsLoading(false);
};
fetchData();
};
Практические советы
- Используйте
useEffectдля управления состоянием после выполнения API-запроса. - Добавьте флаги загрузки для отображения состояния загрузки.
- Замораживайте UI во время выполнения запросов.
- Используйте функциональные методы для управления состоянием.
Заключение
Промежуточное состояние между вызовами setState может вызывать проблемы в приложениях React. Использование флагов загрузки, заморозки UI и функциональных методов помогут управлять состоянием более эффективно и избежать нежелательных промежуточных состояний.