React Hooks: отложенные перерывы загрузки useLayoutEffect? - PullRequest
0 голосов
/ 16 февраля 2019

Мое веб-приложение имеет верхнюю панель навигации, которая может меняться по высоте.Он прикреплен к верхней части экрана, с позицией CSS: исправлено.Чтобы переместить содержимое страницы под ним, у меня есть разделитель div, который обновляет его высоту, чтобы она соответствовала высоте заголовка, и опускает все остальное вниз.

Я обновляю свое приложение, чтобы использовать ловушки React.У меня есть useLayoutEffect крючок, который проверяет высоту панели навигации и обновляет высоту проставки, чтобы соответствовать.Согласно React docs :

В отличие от componentDidMount или componentDidUpdate, эффекты, запланированные с помощью useEffect, не блокируют браузер от обновления экрана.Это делает ваше приложение более отзывчивым.Большинство эффектов не должно происходить синхронно.В редких случаях, когда они это делают (, например, измерение макета ), существует отдельный хук useLayoutEffect с API, идентичным useEffect.

То, что я, похоже, обнаружил,Реагирует ли ленивая загрузка на разрывы useLayoutEffect.Вот CodeSandBox:

https://codesandbox.io/s/5kqxynp564

В навигационной панели скрыт div, содержащий текст «ЕСЛИ ВЫ МОЖЕТЕ УВИДЕТЬ, ЧТО ЭТО ИСПОЛЬЗУЕТСЯ ВНЕ РАБОТАЕТ».Когда используется прямой импорт, размер элемента div над этим текстом изменяется в соответствии с панелью навигации, сдвигая текст вниз под панелью навигации, и текст становится видимым.При использовании React.lazy useLayoutEffect (в AppBarHeader.js) не работает.

Ленивая загрузка происходит в App.js:

//LOADING <COUNTER/> THIS WAY WORKS
// import Counter from "./Counter";

//LAZY LOADING <COUNTER/> THIS WAY BREAKS useLayoutEffect
const CounterPromise = import("./Counter");
const Counter = React.lazy(() => CounterPromise);

Что я пропускаю?

1 Ответ

0 голосов
/ 16 февраля 2019

Похоже, что это фактическая ошибка во времени выполнения useLayoutEffect для компонента в Suspense, где какой-то другой компонент загружается с отложенным доступом.Если AppBarHeader загружен с отложенной загрузкой, а Counter - нет, он работает нормально, но с загруженной с задержкой Counter, AppBarHeader useLayoutEffect выполняется до того, как полностью отобразится в DOM (высота по-прежнему равна нулю).

Эта песочница"исправляет" ее очень хакерским способом, который помогает дополнительно продемонстрировать, что происходит.

Я добавил следующее к App.js:

  replaceRefHeader = () => {
    this.setState({ ref_header: React.createRef() });
  };

и затем передал это Counter:

<Counter replaceRefHeader={this.replaceRefHeader} history={routeProps.history} />

Затем в Counter:

const Counter = ({ replaceRefHeader }) => {
  useLayoutEffect(() => {
    replaceRefHeader();
  }, []);

и затем я поместил [props.ref_header] в массив зависимостейиз AppBarHeader s useLayoutEffect.

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

Я зарегистрировал новую проблему здесь: https://github.com/facebook/react/issues/14869

...