이 글은 자바스크립트 환경에서 스크롤의 방향을 알아내 이를 적용하는 방법인 아래의 글을 React 앱에서 구현하는 예제입니다.

더 알아보시려면 아래 링크 참조 바랍니다.
https://webisfree.com/2019-12-16/[자바스크립트]-스크롤-이벤트에서-스크롤-방향-알아내는-방법


# 리액트 환경에서 스크롤 방향 알아내기
React 역시 자바스크립트 환경이므로 동일하게 구현할 수 있습니다. 아래 예제는 스크롤 방향에 따라 class명을 다르게 추가하여 다이나믹한 Header 컴포넌트를 만드는 것이 목적입니다.

예를들어 Header 영역이 스크롤을 아래로 내릴 경우에는 고정되지 않고 스크롤을 올릴 경우에만 고정되어 어디에서든 보여줄 수 있는 리액트 앱 구현의 예제입니다.

"스크롤을 올릴 경우에만 Header 컴포넌트를 고정해 보여주자"


그럼 아래에서 하나씩 만들어 봅니다. 


! React Header 컴포넌트 만들기
아래와 같이 Header 컴포넌트를 타입스크립트의 tsx로 만들어 보았습니다.

먼저 Header 컴포넌트를 간단하게 만듭니다.
import * as React from 'react';
interface IProps {
}
interface IState {
  scrollDirection?: number
}
class Header extends React.Component<IProps, IState> {
  ...
}

export default Header;

상태값 scrollDirection는 스크롤의 방향을 저장하려고 합니다. 스크롤이 위로 향하면 -1을 반대로 내려가면 1의 값을 가지게 됩니다. 이를 사용하여 현재 방향을 알 수 있겠죠. 이 값을 header 태그의 적용하여 다른 클래스 이름을 가지게 됩니다
const { scrollDirection } = this.state;

<header className= {
  'scroll-direction' + scrollDirection
>
  ...
</header>

여기서  클래스명은 두 가지가 사용되어 실제 렌더링되게 됩니다.
<header class="scroll-direction-1"></header>
<header class="scroll-direction1"></header>

다음으로 페이지가 열리게되면 detectScrollDirection() 함수를 실행해야 합니다. componentDidMount() 라이프사이클 함수를 사용하여 함수를 실행하게 됩니다. detectScrollDirection()는 스크롤의 위치를 계산해 방향을 업데이트 합니다. 전체 코드는 아래와 같죠.

@ detectScrollDirection 함수코드
detectScrollDirection = () => {
  const { scrollDirection } = this.state;
  let savedNum = 0;

  document.addEventListener('scroll', () => {
    let nowScrollTop = document.documentElement.scrollTop;
    if ((nowScrollTop - savedNum) >= 0 && (scrollDirection !== 1)) {
      savedNum = nowScrollTop;
      this.setState({
        scrollDirection: 1
      });
    }
    else if ((nowScrollTop - savedNum) < 0 && (scrollDirection !== -1)) {
      savedNum = nowScrollTop;
      this.setState({
        scrollDirection: -1
      });
    }
  });
};

소스를 잠깐 설명하자면...
이전 스크롤 위치를 저장하고 저장된 값과 현재 스크롤 위치를 비교하여 더 큰 값에 따라 1, -1의 값을 비교문을 사용하여 state 상태값을 변경하는 코드입니다.


여기까지 모든 소스를 알아보았습니다. 아래는완성된 전체 소스 코드입니다.
import * as React from 'react';
interface IProps {
}
interface IState {
  scrollDirection?: number
}
class Header extends React.Component<IProps, IState> {
  componentDidMount() {
    this.detectScrollDirection();
  }

  detectScrollDirection = () => {
    const { scrollDirection } = this.state;
    let savedNum = 0;

    document.addEventListener('scroll', () => {
      let nowScrollTop = document.documentElement.scrollTop;
      if ((nowScrollTop - savedNum) >= 0 && (scrollDirection !== 1)) {
        savedNum = nowScrollTop;
        this.setState({
          scrollDirection: 1
        });
      }
      else if ((nowScrollTop - savedNum) < 0 && (scrollDirection !== -1)) {
        savedNum = nowScrollTop;
        this.setState({
          scrollDirection: -1
        });
      }
    });
  };

  render() {
    const scrollDirection = this.state;
    return (
      <header className= {
        'scroll-direction' + scrollDirection
      >
        헤더입니다.
      </header>
    )
  }
}

export default Header;

여기까지 React 앱에서 스크롤 방향을 구하고 다이나믹하게 동작할 수 있도록 클래스를 추가하는 예제를 만들어보았습니다.