React 래퍼 구성 요소: 스크롤 가능

목표:
마우스 휠을 사용하여 주어진 구성 요소를 세로로 스크롤할 수 있도록 하는 React 구성 요소를 만듭니다.

Scrollable 구성 요소의 영역은 노란색이고 내부 테이블은 스크롤 가능합니다.


다음 2개의 파일을 생성합니다.

첫째, 새로운 React 사용자 정의 후크(useScroll.ts)는 스크롤 상자의 "ref"에 대한 "휠"이벤트 리스너를 추가(그리고 메모리 누수를 방지하기 위해 자동으로 제거)하는 기능을 제공합니다. 이벤트는 매개변수로 "up"또는 "down"을 사용하여 제공된 "onScroll"함수를 호출합니다.

import { useEffect } from "react";

const useScroll = (
  ref: React.RefObject<HTMLElement>,
  onScroll: (direction: "up" | "down") => void
) => {
  const callOnScroll = (event: Event): void => {
    // @ts-ignore
    const wheelEvent = event as React.WheelEvent<HTMLElement>;
    onScroll(wheelEvent.deltaY > 0 ? "up" : "down");
  };

  // ------------------------------------
  useEffect(() => {
    if (ref && ref.current) {
      ref?.current?.addEventListener("wheel", callOnScroll);
    }

    return () => {
      ref?.current?.removeEventListener("wheel", callOnScroll);
    };
  }, [ref, ref?.current, onScroll]);
};

export default useScroll;


그런 다음 새 래퍼 React 구성 요소(Scrollable.tsx) 내에서 "div"가 다른 구성 요소를 자식으로 래핑합니다. 제공된 "onScroll"함수를 호출하기 위해 "wheel"이벤트를 첨부할 수 있도록 "ref"를 만듭니다. 또한 div 내부의 커서를 변경하여 스크롤 가능한 영역에 진입했음을 표시합니다.

import React, { useRef } from "react";
import styled from "styled-components";

// @ts-ignore
import { useScroll } from "hooks";

const Container = styled.div`
  position: relative;
  background-color: beige;
  padding: 5px;
`;

const ScrollIcon = styled.div`
  position: absolute;
  right: 10px;
  font-size: 24px;
`;

type Props = {
  onScroll: (direction: "up" | "down") => void;
  children: React.ReactNode;
};

// ------------------------------------
const Scrollable = ({ onScroll, children }: Props) => {
  const refBoxWithScroll = useRef(null);

  useScroll(refBoxWithScroll, onScroll);

  // ------------------------------------
  return (
    <Container ref={refBoxWithScroll}>
      <ScrollIcon>🡙</ScrollIcon>
      {children}
    </Container>
  );
};

export default Scrollable;


(원하는 경우 styled & Container & ScrollIcon에 대한 정의를 제거하고 "Container"대신 "div"를 사용할 수 있습니다.)

마지막으로 다른 React 구성 요소에서 Scrollable 내부에 테이블 구성 요소를 래핑합니다. 커서가 Scrollable 안에 있을 때 마우스 휠을 움직이면 주어진 onScroll 함수가 호출됩니다. onScroll 함수는 "offset"상태 변수를 증가시키거나 감소시킵니다. 그리고 테이블은 이 "오프셋"에서 시작하여 10개의 행을 표시하므로 테이블이 스크롤됩니다.

...
const onSelectedFieldsTableScroll = (direction: "up" | "down") => {
  if (direction === "up" && matchOffset < matchIndexes.length - pageSize) {
    setMatchOffset(matchOffset + 1);
  } else if (direction === "down" && matchOffset > 0) {
    setMatchOffset(matchOffset - 1);
  }
};
...
return (
  ...
      <Scrollable onScroll={onSelectedFieldsTableScroll}>
        <SelectedFieldsTable rows={rows} />
      </Scrollable>
  ...


수정/제안 환영합니다.

좋은 웹페이지 즐겨찾기