본문 바로가기
React/Next.js

[NextJS] Isotope-layout `window is not define` 오류 해결하기

by 검은냥냥이 2023. 1. 1.

Isotope `window is not define`

`NextJS`에서 `isotope-layout`를 사용하려고 하면, `SSR` 환경에서는 `window is not define` 오류가 발생할 수 있습니다. 그래서 `Isotope`를 사용하는 곳을 `SSR을 풀어주고 다이내믹 링크를 통하여 해결`해볼 수 있습니다.

 

예제

`Home.tsx`

const DynamicPortfolio = dynamic(
  () => import('src/components/Portfolio/portfolio'),
  {
    ssr: false,
  },
)

export default function Home() {
	return (
    	<>
        	 {/* <Navbar /> */}
             {/* ... 등등 */}
             <DynamicPortfolio />
        </>
    )
}

 

`Portfolio.tsx`

declare module Portfolio {
  interface Data {
    label: string
    filter: string
    isActive: boolean
  }
}
export default function Portfolio() {
    const isotope = useRef<Isotope | null>()
    const [filterKey, setFilterKey] = useState('*')
    const [isotopeFilterData, setIsotopeFilterData] = useState<
    Array<Portfolio.Data>>([
        {
          label: 'ALL',
          filter: '*',
          isActive: true,
        },
        {
          label: 'Branding',
          filter: 'brand',
          isActive: false,
        },
        {
          label: 'Mobile App',
          filter: 'web',
          isActive: false,
        },
        {
          label: 'Creative',
          filter: 'graphic',
          isActive: false,
        },
    ])

    const handleFilterKeyChange = (index: number, filter: string) => {
        isotopeFilterData.map((e) => (e.isActive = false))
        isotopeFilterData[index].isActive = true
        setIsotopeFilterData([...isotopeFilterData])
        setFilterKey(filter)
    }

    useEffect(() => {
        setTimeout(() => {
          isotope.current = new Isotope('.filter-container', {
            itemSelector: '.items',
            layoutMode: 'masonry',
          })
          return () => isotope.current?.destroy()
        }, 1000)
    }, [])

    useEffect(() => {
        if (filterKey === '*') {
          isotope.current?.arrange({ filter: `*` })
        } else {
          isotope.current?.arrange({ filter: `.${filterKey}` })
        }
    }, [filterKey])
  
	return (
		<>
        	{/* 필터 */}
            <div className="filter">
              {isotopeFilterData.map((e, i) => (
                <span
                  key={i}
                  className={e.isActive ? 'active' : ''}
                  data-filter={e.filter}
                  onClick={() => handleFilterKeyChange(i, e.filter)}
                >
                  {e.label}
                </span>
              ))}
			</div>
            {/* 본문 */}
            <div className="gallery filter-container full-width">
            <div
              className={`${
                grid === 3
                  ? 'col-lg-4 col-md-6'
                  : grid === 2
                  ? 'col-md-6 lg-mr'
                  : 'col-12'
              } items graphic wow fadeInUp`}
              data-wow-delay=".4s"
            >
                  <div className="item-img">
                    <Link
                      href={`/project-details2/project-details2-dark`}
                      className="imago wow"
                      passHref
                    >
                      <img src="/img/portfolio/portfolio/1/1.jpg" alt={''} />
                      <div className="item-img-overlay"></div>
                    </Link>
                  </div>
                  <div className="cont">
                    <h6>Creativity Demand</h6>
                    <span>
                      <Link href="/works/works-dark">Design</Link>,{' '}
                      <Link href="/works/works-dark">WordPress</Link>
                    </span>
                  </div>
                </div>
        	</div>
		</>
      )
}

예제 코드이지만, 중요한 핵심은 다이나믹 링크를 통한 Import입니다.

 

Isotope 문서

 

Isotope · Layout modes

Layout modes Isotope can position items with different layout modes. Set and change the layout mode with the layoutMode option. masonry fitRows cellsByRow vertical packery masonryHorizontal fitColumns cellsByColumn horiz $grid.isotope({...}) 1 2 3 4 5 6 7

isotope.metafizzy.co

 

728x90
사업자 정보 표시
레플라 | 홍대기 | 경기도 부천시 부일로 519 화신오피스텔 1404호 | 사업자 등록번호 : 726-04-01977 | TEL : 070-8800-6071 | Mail : support@reafla.co.kr | 통신판매신고번호 : 호 | 사이버몰의 이용약관 바로가기