Framework/React

[React] div scroll ๋งจ ์œ„๋กœ ์˜ฌ๋ฆฌ๊ธฐ / scroll ์ปจํŠธ๋กค ํ•˜๋Š” ๋ฐฉ๋ฒ• (useRef ์‚ฌ์šฉ)

yuri lee 2023. 3. 6. 18:58
๋ฐ˜์‘ํ˜•

Intro

์•ˆ๋…•ํ•˜์„ธ์š”. ์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” React scroll ์Šคํฌ๋กค์„ ์ปจํŠธ๋กคํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

 

My case

์ €์˜ ๊ฒฝ์šฐ ์ปดํฌ๋„ŒํŠธ ํ™”๋ฉด์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑ๋˜์–ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ์‹œ๊ธ€ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์žˆ๊ณ , ํŠน์ • ๊ฒŒ์‹œ๊ธ€์„ ํด๋ฆญํ•˜๋Š” ์ˆœ๊ฐ„ ํŠน์ • ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด ๋ณด์ด๊ณ , ์•„๋ž˜๋กœ ๋‹ค๋ฅธ ๊ฒŒ์‹œ๊ธ€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์‹  ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์ค‘ ํ•˜๋‚˜๋ฅผ ํด๋ฆญํ•˜๋ฉด, ๋ณธ๋ฌธ ๋‚ด์šฉ์ด ๋ณ€ํ•˜๋Š” ํ˜•์‹์ž…๋‹ˆ๋‹ค. 

 

How to solve the problem

 

1. ๋Œ€์ƒ div์— ref๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. 

const postDetailRef = useRef<HTMLDivElement>(null);

 

2. ์ •์˜ํ•œ ref ๊ฐ’์„ div tag์— ํ• ๋‹นํ•ด์ค๋‹ˆ๋‹ค. 

<div ref={postDetailRef}>
  {postDetail && (
    <section>
      <h2>{postDetail.title}</h2>
      <div>{postDetail.content}</div>
    </section>
  )}
  {recentpost && recentpost.length > 0 && (
    <section >
      <h2>{postDetail?.categoryName}more post</h2>
      <div >
        {recentpost?.map((item: postRes, index: number) => {
          return (
            <button
              type="button"
              onClick={() => {
                props.eventpostDetail(true, item.postId);
              }}
            >
              <p>{item.title}</p>
            </button>
          );
        })}
      </div>
    </section>
  )}
</div>

 

3. ์ƒ์„ธ ํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜์— scrollTop ๊ฐ’์„ 0์œผ๋กœ ํ• ๋‹นํ•ด์ค๋‹ˆ๋‹ค .

  const getpostDetail = async (postId: number) => {
    const { data } = await postAPI.getpostDetail(postId);
    if (data.status === "200") {
      setpostDetail(data.data);
      if (postDetailRef?.current?.scrollTop) {
        postDetailRef.current.scrollTop = 0;
      }
    }
  };

 

 

์•„๋ž˜๋Š” ์ „์ฒด ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š” :) 

const postDetail: NextPage<Props> = (props) => {
  const [postDetail, setpostDetail] = useState<postDetailRes>();
  const [recentpost, setRecentpost] = useState<postRes[]>();
  const postDetailRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    getpostDetail(props.id);
    getRecentpostDetail(props.id);
  }, [props.id]);

  const getpostDetail = async (postId: number) => {
    const { data } = await postAPI.getpostDetail(postId);
    if (data.status === "200") {
      setpostDetail(data.data);
      if (postDetailRef?.current?.scrollTop) {
        postDetailRef.current.scrollTop = 0;
      }
    }
  };
  const getRecentpostDetail = async (postId: number) => {
    const { data } = await postAPI.getRecentpostDetail(postId);
    if (data.status === "200") {
      setRecentpost(data.data);
    }
  };

  return (
    <div ref={postDetailRef}>
      {postDetail && (
        <section>
          <h2>{postDetail.title}</h2>
          <div>{postDetail.content}</div>
        </section>
      )}
      {recentpost && recentpost.length > 0 && (
        <section >
          <h2>{postDetail?.categoryName}more post</h2>
          <div >
            {recentpost?.map((item: postRes, index: number) => {
              return (
                <button
                  type="button"
                  onClick={() => {
                    props.eventpostDetail(true, item.postId);
                  }}
                >
                  <p>{item.title}</p>
                </button>
              );
            })}
          </div>
        </section>
      )}
    </div>
  );
};

export default postDetail;
๋ฐ˜์‘ํ˜•