인프런 커뮤니티 질문&답변

Incursio님의 프로필 이미지
Incursio

작성한 질문수

[리뉴얼] React로 NodeBird SNS 만들기

해시태그 검색하기

안녕하세요 swr ssr에 대해 질문 드립니다.

해결된 질문

작성

·

385

0

import React from 'react';
import useRouter } from 'next/router';
import Head from 'next/head';
import END } from 'redux-saga';
import axios from 'axios';
import useSelector } from 'react-redux';
import useSWR from 'swr';
import PropTypes from 'prop-types';
import wrapper from '../../store/configureStore';
import AppLayout from '../../components/AppLayout';
import IllustCard from '../../components/IllustCard';
import LOAD_MY_INFO_REQUEST } from '../../reducers/user';
// import { LOAD_POST_REQUEST } from '../../reducers/post';

const fetcher = (url) => axios.get(url, { withCredentials: true }).then((result) => result.data);

const Illustration = ({ post: initialPost }) => {
  const router = useRouter();
  const { id } = router.query;
  //   const { singlePost } = useSelector((state) => state.post);

  const { data: postData, error: postError } = useSWR(`http://localhost:3100/api/post/${id}`, fetcher, { initialPost });

  if (postError) {
    console.error(postError);
    return <div>포스트 로딩 중 에러가 발생했습니다.</div>;
  }

  return (
    <AppLayout>
      {/* <Head>
        <title>{postData.User.nickname}님의 글</title>
        <meta name="description" content={postData.caption} />
        <meta name="og:title" content={`${postData.User.nickname}님의 게시글`} />
        <meta name="og:description" content={postData.caption} />
        <meta name="og:image" content={postData.Images[0] ? postData.Images[0].src : 'https://nodebird.com/favicon.ico'} />
        <meta name="og:url" content={`https://nodebird.com/post/${id}`} />
      </Head> */}
      <IllustCard post={postData} />
    </AppLayout>
  );
};

export const getServerSideProps = wrapper.getServerSideProps(async (context) => {
  console.log('getServerSideProps start');
  const cookie = context.req ? context.req.headers.cookie : '';
  axios.defaults.headers.Cookie = '';
  if (context.req && cookie) {
    axios.defaults.headers.Cookie = cookie;
  }
  context.store.dispatch({
    type: LOAD_MY_INFO_REQUEST,
  });
  const post = await fetcher(`http://localhost:3100/api/post/${context.params.id}`);
  context.store.dispatch(END);
  console.log('getServerSideProps end');
  await context.store.sagaTask.toPromise();
  return { props: { post } };
});

Illustration.propTypes = {
  post: PropTypes.object.isRequired,
};

export default Illustration;

노드버드 강좌를 보고 따로 제작 중인 프로젝트입니다.

swr에 말씀해주신 것 처럼 ssr를 적용해봤는데, 생각처럼 안되고 

이 오류가 뜹니다. 그런데 <Illustration post={postData}/>

부분을 {postData && <Illustration post={postData} />} 이런식으로 방어해야 잘 되더라고요. 그런데 ssr은 아래의 getServerSideProps에서 return한 props 데이터를 가지고 와서 뿌려주는거라 postData가 없을 수가 없을 거 같은데.. 

getServerSideProps 안에서 console.log(post)를  찍어보면 데이터를 잘 가져온 걸로 보이는데, props로 전달되면서 뭔가 이상이 생긴건지 아니면 서버사이드 렌더링 자체가 이상하게 되고 있는건지 잘 모르겠습니다. LOAD_MY_INFO_QUEST는 정상적으로 작동해서 HYDRATE 실행 시 me에 데이터는 정상적으로 채워집니다. 뭐가 문제일까요?

답변 10

1

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

아, 값 꺼내오는 부분은 제 다른 코드랑 착각했습니다. postData &&으로 방어한 다음에 props 있나 확인해보세요.

1

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

console.log('initialPost', initialPost)하면 값이 들어있긴 한가요?

저는 saga와 return props를 같이 써본적이 없어서요. 제 profile.js에서도 보시면 redux로부터 값을 꺼내와서 swr에 넣었습니다.

1

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

{ initialData: intialPost } 입니다.

0

Incursio님의 프로필 이미지
Incursio
질문자

아 그렇군요 답변 감사합니다!

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

페이지에서만 getServerSideProps를 쓸 수 있습니다.

0

Incursio님의 프로필 이미지
Incursio
질문자

아 그리고 지금 보면 각 페이지에서 LOAD_MY_INFO_REQUEST를 보내고 계신데, 이거를 APPLAYOUT 로 올려서 써도 될까요?

0

Incursio님의 프로필 이미지
Incursio
질문자

와우 결국 해결했습니다. _app.js에서 props에 {Component, pageProps} 를 넘겨주고, render 부분에

<Component {...pageProps} /> 하면 props가 제대로 넘어오네요. 이거땜에 몇시간을 날려묵었는지 모르겠네요ㅋㅋㅋ

답변해주셔서 감사합니다!

0

Incursio님의 프로필 이미지
Incursio
질문자

아 찍어보니 undefined가 뜨네요. 이렇게 되면 리턴하거나 받아오는데에 이상이 생긴건데.. 리턴이나 받아오는데나 제 눈으로는 아무리 찾아봐도 못찾겠네요. swr ssr라고 검색해도 관련 자료가 별로 없어서 그런데 제로초님이 swr ssr 쓰신 repository나 참고하신 것이 있나요?

0

Incursio님의 프로필 이미지
Incursio
질문자

컴포넌트 렌더링전에 getServerSideProps 에서 오류가 나서 console.log를 찍어볼 수가 없네요...

그리고 redux로부터 값을 꺼내왔다는게 어느 부분인가요?

        const { data: followersData, error: followerError } = useSWR(`${backUrl}/user/followers?limit=${followersLimit}`, fetcher);

  const { data: followingsData, error: followingError } = useSWR(`${backUrl}/user/followings?limit=${followingsLimit}`, fetcher);

제로초님 nodebird/ch7/front/pages/profile.js 에서 swr 쓰신 부분인데 리덕스 값을 찾아쓴건 못찾겠어요.

0

Incursio님의 프로필 이미지
Incursio
질문자

방금 고쳐봤는데 똑같은 오류가 뜹니다.  _document를 확인해봐도 제로초님 노드버드랑 코드가 똑같은데 또 어디가 문제일까요?

Incursio님의 프로필 이미지
Incursio

작성한 질문수

질문하기