NextJS - 3 (SSR)

J-USER·2021년 7월 6일
0

NextJS

목록 보기
4/6
post-thumbnail

이전 포스팅에서 상품을 보여주는 과정에서 약간의 시간과 자연스럽지 못한 퍼포먼스를 보였는데요. 이것을 개선하기 위해 크게 두가지 방법을 생각했습니다.

1.로딩 페이지 삽입!
2. SSR ( 😄 왜 SSR이 방법인지 궁금한 사람은 클릭!)

로딩 페이지 제작.

로딩 페이지 제작은 아주 기본적이고 간단한 방법입니다. 대부분의 외부 디자인 라이브러리의 경우 (bootstrap, semantic-ui-react 등... ) 은 Loading 과 관련된 페이지를 제공하기 때문에 각자 쓰시는 것에서 불러온 후, 데이터를 저장한 후에 loading 의 논리 구조를 반대로 설정해주면 됩니다.

#index.js

import { Divider, Header, Loader } from 'semantic-ui-react'

export default function Home() {
  const API_URL = "http://makeup-api.herokuapp.com/api/v1/products.json?brand=maybelline"
  const [list,setList] = useState([]);
  const [isLoading, setIsLoading] = useState(true); # 로딩값 초기 설정.
  
  useEffect(() => {
    axios.get(API_URL)
    .then((res) =>{
    setList(res.data) // 데이터 입력, 설정
    console.log(res.data)
    setIsLoading(false); // 이후에 로딩 값 변경
    })
  }, [])
  return (
    <div>
      <Head>
        <title>HOME | JUSER</title>
      </Head>
      {
        isLoading && (<div style= {{padding : "300px 0"}}> 
          <Loader inline="centered" active> // 로딩 중일때...... 
            Loading
          </Loader>
        </div>)
      }
      {
        !isLoading &&(
          <>
          {로딩이 끝나면 보여주고 싶은 구조}
      </>
        )
      }
      
    </div>
  )
}

위와 같이 대충 저런 논리 구조로 작성하면 됩니다. 그런데 조금 너무 간단하고 굳이 NextJs 가 아니라도 할 수 있는 해결법입니다.

NextJs의 특성을 이용한 솔루션을 한번 보시죠.

SSR 을 사용한 퍼포먼스 개선.

SSR 을 사용한 솔루션을 사용하기 위해서는 getServerSideProps 함수를 사용하는 방법입니다.
getServerSideProps 는 빌드와 상관없이, 매 요청마다 데이터를 서버로부터 가져옵니다.

작동 포멧 ,논리는 👇

function Page({ data }) {
  console.log(this.props.data)
 //res.json()이 찍힙니다
}


export async function getServerSideProps() {
 
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  return { props: { data: data } }
}

export default Page

위의 로직은 fetch api를 통해 data값을 가져오고 data를 Page component에서 this.props.data로 접근이 가능한 형식입니다.

이 로직을 제 코드에 적용해보도록 하겠습니다.
Before 👇

const Post = () => {
  const [item, setItem] = useState({})
  const router = useRouter()
  const { id } = router.query
  const [isLoading, setIsLoading] = useState(true);

  const API_URL = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`

  useEffect(() => { 
    if (id&& id >0){
      axios.get(API_URL)
    .then(res =>{
      setItem(res.data);
      setIsLoading(false);
    })
    }
    
    
  }, [id])
  return <>{ isLoading ? (<div style= {{padding : "300px 0"}}> 
  <Loader inline="centered" active>
    Loading
  </Loader>
</div>) : <Item item ={item}/>}</>
}

export default Post;

After 👇

const Post = ({item}) => {
  return <>{ item && <Item item ={item}/>}</>
}

export default Post;


export async function getServerSideProps(context) {
  const id = context.params.id;
  const apiUrl = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`
  const res = await axios.get(apiUrl);
  const data= res.data

  return {
    props: {
      item : data
    }
  }

}

네 아주 놀라운 변화가 있었는데요. 코드가 훨씬 간편해진게 보이시나요?! 🔥

🙋 파라미터로 받는 context는 뭔가욥?!

🤖 context 에는 여러가지 정보가 들어있습니다. params, 요청 등과 같은 데이터들이 들어있죠.

context 하위 키👉

params: 이전에 나온 내용과 동일
req: The HTTP request object.
res: The HTTP response object.
query: The query string.
preview: 나중에
previewData: 나중에

🙋 근데 이러면 대체 뭐가 더 좋나요??

🤖 최신상태유지 , SEO 향상

이전에는 그저 pre - rendering 된 상태일 뿐입니다. 소스를 보시면 메타테그에 관련된 내용이 없었지만,

이후에는 아래와 같이 메타 테그로 인한 상품 설명 부분이 들어가게 되었습니다. 만약 배포하게 된다면 저 내용에 관련된 검색어를 검색하면 저 상품이 딱 나오겠죠?

또한 요청 받으면 거기에 대해서 렌더링을 그때그때 진행하기 때문에 퍼포먼스 적으로 더이상 기다리지도, 로딩창을 보지도 않아 체감상 훨씬 자연스럽고 빠른 속도를 체감할 수 있습니다. ( 실제로는 요청 자체가 늘어나기 때문에 퍼포먼스는 낮아질 수 있지만..😅 )

아! 그리고 실시간 데이터를 호출하기 때문에 가격 변동이나, 다이나믹하게 변하는 데이터를 즉각 반영할 수 있다는 장점도 있죠! 😄

에러...

아니 그런데 자꾸 콘솔창에 저렇게 시뻘건 글씨로 에러가 뜨는 것을 볼 수 있습니다. Ref말고 딴거 써라!!!!라고 하는데....

아래는 NextJS 공식 문서에 나와있는 문구입니다. 직역하자면,

이전까지는 원래 Link 에 as 써줬음!

'as'는 브라우저 주소창에 나오는 주소를 의미하는데요. 즉, 실제 사용자가 보는 주소를 의미합니다.

<Link href="/post/[pid]" as="/post/abc">
  <a>First Post</a>
</Link>

href는 넥스트 JS 가 실제로 가는 경로이고 , as 는 사용자에게 보여줄 경로를 의미합니다.

# itemList.js
...
<Link href={`/view/${item.id}`}>
...
위의 코드를...

...
<Link href="/view/[id]" as={`/view/${item.id}`}>
...
요렇게 바꿔주면

에러가 시원하게 사라졌습니다!!😄

profile
호기심많은 개발자

0개의 댓글