Предотвращение мигания пользовательского интерфейса при загрузке асинхронных данных в React.js

У меня есть некоторые данные в IndexedDB, к которым можно получить доступ только асинхронно. Я хочу создать пользовательский интерфейс React.js, используя эти данные. Общая идея заключается в том, что у меня будет несколько компонентов React, которые загружают данные из IndexedDB и отображают некоторый пользовательский интерфейс на основе этих данных, и пользователь сможет переключаться между тем, какой компонент отображается в данный момент.

Моя забота заключается в том, что я не знаю, как изящно выполнить это без какого-либо излишнего мигания пользовательского интерфейса. Я могу выполнить асинхронную загрузку данных в componentDidMount и поместить данные в this.state, но затем render будет вызываться до его завершения, заставляя меня либо отображать ничего, либо отображать некоторые данные заполнитель для небольшой доли секунды в то время как данные из IndexedDB извлекаются.

Я предпочел бы, чтобы он не был render, пока не загрузятся данные из IndexedDB. Я знаю, что загрузка не займет много времени, и я предпочел бы, чтобы предыдущий компонент продолжал отображаться, пока загружаются новые данные, поэтому есть только один мерцающий (старый → новый), а не два (старый → пустой/заполнитель → новый). Это больше похоже на работу обычной веб-страницы. Когда вы нажимаете ссылку с одного веб-сайта на другой, ваш браузер не отображает пустой экран/заполнитель, пока он ждет ответа от сервера с сайта.

Я думаю, что могу выполнять загрузку своих данных за пределами компонента React перед вызовом React.render, а затем передать его через this.props. Но это кажется беспорядочным, потому что вложенные компоненты станут сложными, и некоторые из моих компонентов будут со временем обновляться и вытаскивать новые данные из IndexedDB через тот же самый код, который их инициализирует. Таким образом, это кажется идеальным вариантом для хранения данных в this.state, потому что тогда я мог бы обновить его внутри самого компонента, когда я получу сигнал о том, что новые данные доступны. Инициализация и обновление были бы такими же легкими, как вызов функции this.loadData(), которая устанавливает некоторые значения в this.state... но тогда у меня есть вышеупомянутое дополнительное мерцание.

Есть ли у кого-нибудь лучшие идеи? Какое каноническое решение этой проблемы? Это действительно просто, чтобы миллисекунды пробела/заполнителя мерцали повсюду?

Ответ 1

Из комментариев это похоже на поведение, которое у вас было в предыдущей реализации (ожидание навигации до тех пор, пока вы не получите необходимые данные) - это желаемая цель. Если это так, лучшим способом сделать это без мерцания будет использование какого-либо внешнего объекта для управления состоянием и передачи данных в качестве реквизита, когда он был извлечен.

React Router имеет довольно хорошее решение, в котором он имеет hookTransitionTo для получения данных для данного компонента перед навигацией. Это дает дополнительное преимущество, позволяя вам легко ловить ошибки, если что-то пойдет не так.

Обновлено с помощью новой ссылки:

https://github.com/reactjs/react-router