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

tkdals9048님의 프로필 이미지
tkdals9048

작성한 질문수

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

해시태그 검색하기

Avatar 클릭시 /user/1 로 이동 할 때

작성

·

424

0

오류가 나는데 원인을 파악하기 어려워 질문드립니다!

url에 직접 /user/1 를 입력해서 접근할 경우 아무 문제가 없는데

Link 태그로 클릭해서 이동할 경우 

Unhandled Runtime Error

TypeError: Cannot read property 'nickname' of null

해당 에러가 발생합니다..

제 생각에는 Link 태그를 통해 이동했을 때 getServerSideProps 안에 context.store.dispatch 가 실행되지 않아 에러가 나는 것 같은데

깃헙에 원본 소스와 비교해봐도 어느부분이 문제인지 감이 오질 않아서 질문드립니다ㅠ

답변 11

0

저도 같은 에러인데...혹시 해결하신분 계시나요...?

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

userInfo 가 사용되는 부분에 아래처럼 감싸서 해결할 수 있었습니다!

{userInfo && (
<Head>
     <title>{userInfo.nickname}님의 글</title>
     <meta name="description" content={`${userInfo.nickname}님의 게시글`} />
     <meta property="og:title" content={`${userInfo.nickname}님의 게시글`} />
     <meta property="og:description" content={`${userInfo.nickname}님의 게시글`} />
     <meta property="og:image" content="https://nodebird.com/favicon.ico" />
     <meta property="og:url" content={`https://nodebird.com/user/${id}`} />
   </Head>
)}

0

저도 똑같은 에러가 발생합니다. 주소에 /user/1을 넣어서 이동하면 동작하는데, avatar를 클릭하는 경우는 로딩바가 안돌고, loadUserDone이 false로 변합니다. 그런데 avatar를 새탭에서 여는걸로 클릭하면 정상적으로 로딩이 됩니다. 

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

userInfo 가 사용되는 부분에 아래처럼 감싸서 해결할 수 있었습니다!

{userInfo && (
<Head>
     <title>{userInfo.nickname}님의 글</title>
     <meta name="description" content={`${userInfo.nickname}님의 게시글`} />
     <meta property="og:title" content={`${userInfo.nickname}님의 게시글`} />
     <meta property="og:description" content={`${userInfo.nickname}님의 게시글`} />
     <meta property="og:image" content="https://nodebird.com/favicon.ico" />
     <meta property="og:url" content={`https://nodebird.com/user/${id}`} />
   </Head>
)}

0

저도 같은데  혹시 해결 되셨나요?

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

userInfo 가 사용되는 부분에 아래처럼 감싸서 해결할 수 있었습니다!

{userInfo && (
<Head>
     <title>{userInfo.nickname}님의 글</title>
     <meta name="description" content={`${userInfo.nickname}님의 게시글`} />
     <meta property="og:title" content={`${userInfo.nickname}님의 게시글`} />
     <meta property="og:description" content={`${userInfo.nickname}님의 게시글`} />
     <meta property="og:image" content="https://nodebird.com/favicon.ico" />
     <meta property="og:url" content={`https://nodebird.com/user/${id}`} />
   </Head>
)}

0

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

넵 페이지 주소도 변경 되고, getServerSideProps 내부도 실행이 되는데 로딩바만 안도는거면 서버 사이드 렌더링 셋팅할 때 뭔가 빠트렸나 보네요 강의 다시 확인해보겠습니다!

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

0

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

페이지 주소는 변경되나요? getServerSideProps는 Link 태그를 누르고 넘어갈 때도 서버쪽에서 한 번 호출이 되는지라 상단 로딩바가 돌아야 합니다.

0

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

리듀서쪽도 다시 체크해봐야겠네요 ㅠ

넵 맞아요 제로초님 코드 ch6 폴더에 front 실행시켜서 비교해봤는데 아바타를 클릭했을 때 다르게 작동해요

제로초님 코드는 아바타 클릭시 

제 코드 아바타 클릭시

제 코드에서 아바타를 클릭했을 때 는 로딩바가 안돌아요 이부분은 SSR이 제대로 되고 있지 않다고 봐야하는건가요?

0

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

흠, 제 코드와 복사해서 비교해봤는데 다른 점은 loadUserPostsLoading밖에 없네요.

제 코드 클론받아서 실행해보신 것 같은데 제 코드에서는 __NEXT_REDUX_WRAPPER_HYDRATE__가 호출되나요?

그렇다면 리듀서쪽이 쪽이 문제인 것 같습니다.

리듀서쪽에서 영향이 가는 부분은 store/configureStore.js, reducers가 있습니다.

깃헙에 올리신 뒤 저에게 깃헙 주소를 알려주셔도 됩니다.

0

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

import axios from 'axios';
import React, { useEffect } from 'react';
import { useDispatchuseSelector } from 'react-redux';
import { END } from 'redux-saga';
import { useRouter } from 'next/router';
import Head from 'next/head';
import { CardAvatar } from 'antd';
import { LOAD_USER_REQUESTLOAD_MY_INFO_REQUEST } from '../../reducers/user';
import { LOAD_USER_POSTS_REQUEST } from '../../reducers/post';
import AppLayout from '../../components/AppLayout';
import PostCard from '../../components/PostCard';
import wrapper from '../../store/configureStore';

const User = () => {
  const dispatch = useDispatch();
  const router = useRouter();
  const { id } = router.query;
  const {
    hasMorePostsloadPostLoadingmainPostsretweetError,
  } = useSelector((state=> state.post);
  const { userInfo } = useSelector((state=> state.user);

  useEffect(() => {
    if (retweetError) {
      alert(retweetError);
    }
  }, [retweetError]);

  useEffect(() => {
    function onScroll() {
      if (window.pageYOffset + document.documentElement.clientHeight
        > document.documentElement.scrollHeight - 300) {
        if (hasMorePosts && !loadPostLoading) {
          const lastId = mainPosts[mainPosts.length - 1]?.id;
          dispatch({
            type: LOAD_USER_POSTS_REQUEST,
            data: id,
            lastId,
          });
        }
      }
    }
    window.addEventListener('scroll'onScroll);
    return () => {
      window.removeEventListener('scroll'onScroll);
    };
  }, [hasMorePostsloadPostLoadingidmainPosts]);

  return (
    <AppLayout>
      <Head>
        <title>{userInfo.nickname}님의 글</title>
        <meta name="description" content={`${userInfo.nickname}님의 게시글`} />
        <meta property="og:title" content={`${userInfo.nickname}님의 게시글`} />
        <meta property="og:description" content={`${userInfo.nickname}님의 게시글`} />
        <meta property="og:image" content="https://nodebird.com/favicon.ico" />
        <meta property="og:url" content={`https://nodebird.com/user/${id}`} />
      </Head>
      {userInfo
        ? (
          <Card
            actions={[
              <div key="twit">
                짹짹
                <br />
                {userInfo.Posts}
              </div>,
              <div key="following">
                팔로잉
                <br />
                {userInfo.Followings}
              </div>,
              <div key="follower">
                팔로워
                <br />
                {userInfo.Followers}
              </div>,
            ]}
          >
            <Card.Meta
              avatar={<Avatar>{userInfo.nickname[0]}</Avatar>}
              title={userInfo.nickname}
            />
          </Card>
        )
        : null}
      {mainPosts.map((post=> <PostCard key={post.id} post={post} />)}
    </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,
  });
  context.store.dispatch({
    type: LOAD_USER_POSTS_REQUEST,
    data: context.params.id,
  });
  context.store.dispatch({
    type: LOAD_USER_REQUEST,
    data: context.params.id,
  });
  context.store.dispatch(END);
  console.log('getServerSideProps End');
  await context.store.sagaTask.toPromise();
});

export default User;

입니다!

0

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

user/[id].js 전체 올려주세요.

0

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

넵 다시 확인했는데 프론트 서버 터미널에는 dispatch가 정상적으로 SUCCESS 까지 작동하는데

리덕스 데브툴로 확인해보니 __NEXT_REDUX_WRAPPER_HYDRATE__ 가 실행되지 않고 위 와 같은 에러가 나요

-----------

제로초님 깃헙 소스를 내려받아 실행하면서 비교해봤는데 제로초님 은 아바타 클릭시 리프레쉬 되면서 페이지 이동하는데

제가 작성한 코드는 리프레쉬 되지 않아요 ㅠ

0

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

userInfo가 null인 상황 맞나요?

제일 간단하게 찾는 방법은 리덕스 데브툴을 확인해보는 것입니다. 그리고 console.log(window.__NEXT_DATA__) 해보아서 초기 데이터로 유저 정보가 들어있는지 확인해서 SSR이 제대로 되고있는지 찾아볼 수 있습니다.

tkdals9048님의 프로필 이미지
tkdals9048

작성한 질문수

질문하기