본문 바로가기

Computer Programming/Next

Next.js 13 - loading.tsx , error.tsx, 이미지, 폰트

1. loading.tsx

 

layout.tsx와 같은 위치의 폴더 안에 loading.tsx를 정의해주면 해당하는 return 값이 로딩중에 보여지게 된다.

 

export default function PageLoading() {
  return <div>loading...</div>;
}

 

layout은 보여지고, 그 layout의 children에 해당하는 부분에서 로딩중일 때 실행된다. 정적인 데이터이므로 pre-fetched html에 포함되어있다.

 

-> SSG에서는 확인할 수 없으며 의미도 없다.

즉 loading 이라는 것은 dynamic하게 SSR이나 CSR을 사용할 때 의미가 있음

 

loading.tsx는 한 라우트당 1개씩 지정할 수 있기 때문에, 데이터들 내에서 loading...들을 보여주고싶다면 segments로 나눠서 보여줘야한다.

 

*병렬적으로 의미있는 데이터 먼저 보여주기 (부분적 suspense 사용)

 2개의 데이터 fetch 함수가 있다고 치면, 첫 번째 함수는 await 을 통해 기다렸다가 준비되면 데이터를 보여주고, 동시에 두번째 함수는 Suspense로 감싸서 fallback={<AnotherLoading />}을 수행한다. 그러면 사용자가 두개의 함수 모두 완료될 때 까지 기다릴 필요 없이 의미가 있는 첫번째 데이터를 먼저 보게 된다.

import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'
 
export default function Posts() {
  return (
    <section>
      <Suspense fallback={<p>Loading feed...</p>}>
        <PostFeed />
      </Suspense>
      <Suspense fallback={<p>Loading weather...</p>}>
        <Weather />
      </Suspense>
    </section>
  )
}

혹은 이렇게 의미있는데 데이터마다 따로 loading 파일을 지정할 수 있다.

 

 

 

2. error.tsx

같은 위치에 error.tsx생성

"use client";

import { useEffect } from "react";

type Props = {
  error: Error;
  reset: () => void;
};

export default function ProductsError({ error, reset }: Props) {
  useEffect(() => {
    console.error(error);
  }, [error]);

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>Try again</button>
    </div>
  );
}

reset()함수로 reload 버튼 만들 수 있음

 

리액트 errorboundary를 사용할 수도 있음

error boundary를 중첩시키면 가장 근접한 곳의 error를 보여줌.

<ErrorBoundary FallbackComponent={ErrorFallback}>
  <Login />
</ErrorBoundary>

 

 

3. Image 태그

 

 

로컬 이미지를 사용할 땐 너비와 높이를 지정하지 않아도 그 정도의 공간을 미리 html에서 만들어두며 크기도 자동으로 최적화해줌 ->layout shift가 일어나지 않는다.

외부 url을 사용할 때는 width 와 height를 지정해줘야함

그리고 next.config.js에서 이미지 호스트 허용을 설정해줘야한다.

/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "images.unsplash.com",
      },
    ],
  },
};

module.exports = nextConfig;

 

한 페이지에 사진이 여러장이라면 중요한 사진에 priority를 지정해줄 수 있음

<Image src={clothes} alt="clothes" priority />