programing

리액트 훅을 사용하여 Next.js SSR에서 창 크기를 검출하는 방법

topblog 2023. 3. 14. 21:21
반응형

리액트 훅을 사용하여 Next.js SSR에서 창 크기를 검출하는 방법

Next.js와 react-dates를 사용하여 앱을 만들고 있습니다.

DateRangePicker 컴포넌트와 DayPickerRangeController 컴포넌트가 2개 있습니다.

창 너비가 1180px보다 클 경우 DateRangePicker를 렌더링하고, 이 크기보다 작을 경우 DayPickerRangeController를 렌더링합니다.

코드는 다음과 같습니다.

      windowSize > 1180 ?
           <DateRangePicker
             startDatePlaceholderText="Start"
             startDate={startDate}
             startDateId="startDate"
             onDatesChange={handleOnDateChange}
             endDate={endDate}
             endDateId="endDate"
             focusedInput={focus}
             transitionDuration={0}
             onFocusChange={(focusedInput) => {
               if (!focusedInput) {
                 setFocus("startDate")
               } else {
                 setFocus(focusedInput)
                }
               }}
                /> :
             <DayPickerRangeController
               isOutsideRange={day => isInclusivelyBeforeDay(day, moment().add(-1, 'days'))}
               startDate={startDate}
               onDatesChange={handleOnDateChange}
               endDate={endDate}
               focusedInput={focus}
               onFocusChange={(focusedInput) => {
               if (!focusedInput) {
                 setFocus("startDate")
                 } else {
                  setFocus(focusedInput)
                 }
               }}
              /> 
          }

윈도우 오브젝트와 리액트 훅을 사용하여 윈도우 화면 폭을 이렇게 검출합니다.

그러나 sr 렌더링에 창 개체가 없기 때문에 sr에서는 이 방법을 사용할 수 없습니다.

sr에 관계없이 윈도우 크기를 안전하게 얻을 수 있는 다른 방법이 있나요?

다음 코드를 추가하면 srs에서 탐지 함수를 호출하지 않아도 됩니다.

// make sure your function is being called in client side only
if (typeof window !== 'undefined') {
  // detect window screen width function
}

링크의 완전한 예:

import { useState, useEffect } from 'react';

// Usage
function App() {
  const size = useWindowSize();

  return (
    <div>
      {size.width}px / {size.height}px
    </div>
  );
}

// Hook
function useWindowSize() {
  // Initialize state with undefined width/height so server and client renders match
  // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
  const [windowSize, setWindowSize] = useState({
    width: undefined,
    height: undefined,
  });

  useEffect(() => {
    // only execute all the code below in client side
    // Handler to call on window resize
    function handleResize() {
      // Set window width/height to state
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    }
    
    // Add event listener
    window.addEventListener("resize", handleResize);
     
    // Call handler right away so state gets updated with initial window size
    handleResize();
    
    // Remove event listener on cleanup
    return () => window.removeEventListener("resize", handleResize);
  }, []); // Empty array ensures that effect is only run on mount
  return windowSize;
}

NB: Sergey Dubovik 코멘트로 갱신되었습니다.useEffect는 클라이언트 측에서 실행되므로 윈도우를 검증할 필요가 없습니다.

반면 Darryl RN은 절대적으로 정답을 제시했습니다.한 마디만 하겠습니다.그 존재 여부를 확인할 필요는 없습니다.window안에 있는 물체useEffect왜냐면useEffect클라이언트측에서만 실행되며 서버측에서는 실행하지 않습니다.window오브젝트는 클라이언트 측에서 항상 사용할 수 있습니다.

useEffect(()=> {
   window.addEventListener('resize', ()=> {
       console.log(window.innerHeight, window.innerWidth)
   })
}, [])

사용하고 있는 솔루션은 다음과 같습니다.여기서 발견된 작은 npm 패키지는 use-size입니다.

설치 및 Import가 완료되면 다음과 같이 사용합니다.

const { innerWidth, innerHeight, outerHeight, outerWidth } = useWindowSize();

return (
    <div>Window width: {innerWidth}</div>
)

언급URL : https://stackoverflow.com/questions/63406435/how-to-detect-window-size-in-next-js-ssr-using-react-hook

반응형