Значение clientWidth не является правильным для обрезанного элемента div с динамической шириной c (с использованием useLayoutEffect и SSR) - PullRequest
0 голосов
/ 26 января 2020

У меня есть div (.inner) с динамической шириной c в зависимости от его содержимого.

.inner {
  display: inline-block;
  position: absolute;
}

Это обрезается его родителем (.clipper) с использованием overflow: hidden:

.clipper {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
}

Я хочу, чтобы полная внутренняя ширина элемента не была обрезана, я делаю это так:

useLayoutEffect(() => {
  const { clientWidth: innerWidth } = innerRef.current;
  // work with innerWidth..

  }, []);

Однако, это innerWidth, clientWidth или ширина ограничительной рамки - все возвращаются обрезанное значение (370 в этом случае). The clipped value

Проверка его в DOM показывает его реальную ширину (723). The desired value

Кроме того, после горячей перезагрузки модуля консоль регистрирует нужную ширину один раз ..

Может кто-нибудь просветить меня, что происходит? Это как-то связано с повторным рендерингом или чем-то с console.log?

Ответы [ 2 ]

0 голосов
/ 05 февраля 2020

Я понял это.

Оказывается, что мое неправильное значение clientWidth связано с несоответствием между исходным, не гидратированным пользовательским интерфейсом и предполагаемым пользовательским интерфейсом.

Я думал, что это будет быть исправимым путем ленивой загрузки моего компонента до тех пор, пока клиентская сторона JS не загрузит и не увлажнит компонент, см. вариант 2 здесь :

Однако это не сработало, поэтому я представил немного взломать, используя setTimeout, и useIsomorphicLayoutEffect, чтобы исключить предупреждение SSR useLayoutEffect (см. здесь ).

После тайм-аута я получаю правильное значение DOM.

useIsomorphicLayoutEffect(() => {
  // Check for refs
  if (containerRef.current && innerRef.current) {
    setTimeout(() => {
      const { clientWidth: containerWidth } = containerRef.current;
      const { clientWidth: innerWidth } = innerRef.current;

      maxTransform.current = innerWidth - containerWidth;

      checkForBoundaries();
    }, 1000);
  }
}, [checkForBoundaries]);
0 голосов
/ 04 февраля 2020

Каков размер отображаемого контента

Если вам нужно знать, сколько места занимает фактический отображаемый контент, включая отступы, но не включая границу, поля или полосы прокрутки, Вы хотите использовать свойства Element.clientWidth и Element.clientHeight

Насколько велик контент

Если вам необходимо знать фактический размер контента, независимо от сколько из этого в настоящее время видно, вам нужно использовать Element.scrollWidth и Element.scrollHeight

см. документацию по MDN для получения более подробной информации

...