Как получить текущее окно pageYOffset в стилизованном компоненте? - PullRequest
2 голосов
/ 29 мая 2019

Я борюсь с анимацией перевода, которая зависит от scrollYOffset окна.

У меня есть что-то вроде этого:

const StyledHeading = styled.h1`
  font-size: ${({ theme }) => theme.fontSize.l};
  letter-spacing: 1px;
  font-family: ${({ theme }) => theme.font.firaSans};
  margin: 0;
  transition: 0.25s ease-in-out;
  transform: translateX(${({ offset }) => (offset > 100 ? '-50px' : '0px')});
`;

export default function Navbar() {
  const [offset, setOffset] = useState(window.pageYOffset);

  useEffect(() => {
    window.addEventListener('scroll', () => {
      setOffset(window.pageYOffset);
    });
  });

  return (
    <StyledHeader >
      <StyledWrapper>
        <StyledHeading offset={offset}>
          Bookphiles <i className="fas fa-book-open" />
        </StyledHeading>
        <nav>
          <NavLinks  />
        </nav>
      </StyledWrapper>
    </StyledHeader>
  );
}

Но, похоже, это делается очень неэффективно,потому что каждый свиток вызывает рендеринг DOM.Можно ли это сделать как-нибудь лучше?

Ответы [ 2 ]

1 голос
/ 29 мая 2019

ИМХО, если вы хотите избежать прерывистой анимации, вы должны полагаться на управление DOM refs вместо React render ():

import React, { useState, useEffect, createRef } from 'react';

export default function Navbar() {
  const ref = createRef();

  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
  });

  handleScroll = (e) => {
      const offset = window.pageYOffset;
      ref.current.style.transform = `translateX(${({ offset }) => (offset > 100 ? '-50px' : '0px')})`;
  }

  return (
    //...code
        <StyledHeading ref={ref}>
          Bookphiles <i className="fas fa-book-open" />
        </StyledHeading>
    //..code
  );
}

Обратите внимание, что в моем коде может быть некоторая опечатка, но концепция заключается в том, чтобы не включать повторный рендеринг в управлении прокруткой. Не забудьте удалить прослушиватель перед размонтированием компонента.

0 голосов
/ 29 мая 2019

Попробуйте использовать функцию throttle или debounce из lodash, чтобы ограничить число выполнений вашей функции обработчика событий. Таким образом, обработчик событий будет выполняться не чаще, чем каждые 200 миллисекунд:

window.addEventListener('scroll', _.throttle(() => {
  setOffset(window.pageYOffset);
}, 200));

Это хорошая статья, которая объясняет эту идею более подробно и предоставляет больше примеров: https://css -tricks.com / debouncing-throttling-объяснены-примеры /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...