inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

getStaticProps 사용해보기

redux toolkit ssr 질문

500

i1004gy

작성한 질문수 36

0

계속 똑같은 부분을 질문하고있는데 혹시 똑같은 오류가 발생하고 이 부분 코드는 양이 적고 코드 양이 적어서 오류의 원인을 아는데 용이 할꺼 같아 질문드립니다

pages/about.js

import React from "react";
import { useSelector } from "react-redux";
import Head from "next/head";

import { Avatar, Card } from "antd";
import AppLayout from "../components/AppLayout";
import wrapper from "../store/configureStore";
import { loadUserInfo } from "../reducers/user";

const Profile = () => {
  const { userInfo } = useSelector((state) => state.user);

  return (
    <AppLayout>
      <Head>
        <title>ZeroCho | NodeBird</title>
      </Head>
      {userInfo ? (
        <Card
          actions={[
            <div key="twit">
              짹짹
              <br />
              {userInfo.Posts.length}
            </div>,
            <div key="following">
              팔로잉
              <br />
              {userInfo.Followings.length}
            </div>,
            <div key="follower">
              팔로워
              <br />
              {userInfo.Followers.length}
            </div>,
          ]}
        >
          <Card.Meta
            avatar={<Avatar>{userInfo.nickname[0]}</Avatar>}
            title={userInfo.nickname}
            description="노드버드 매니아"
          />
        </Card>
      ) : null}
    </AppLayout>
  );
};

export const getStaticProps = wrapper.getStaticProps(
  (store) =>
    async ({ req }) => {
      console.log("getStaticProps");
      await store.dispatch(loadUserInfo(1));
    }
);

export default Profile;
reducers/user.js

export const loadUserInfo = createAsyncThunk(
  "/user/LoadUserInfo",
  async (data) => {
    const response = await axios.get(`/user/${data}`, data);
    return response.data;
  }
);

const userSlice = createSlice({
  name: "user",
  initialState,
  reducers: {
    addPostToMe(draft, action) {
      // 값을 하나만 전달해서 값이 바로 payload에 저장이된다
      // 내가 만든 포스트를 me state에 저장하는 reducer
      draft.me.Posts.unshift({ id: action.payload });
    },
    removePostOfMe(draft, action) {
      draft.me.Posts = draft.me.Posts.filter((v) => v.id !== action.payload);
    },
  },
  // 외부에서 action을 만든것은 extraReducers로 가져와서 사용한다 주로 createAsyncThunk로 action을 만들 때 사용한다
  extraReducers: (builder) =>
    builder
      .addCase([HYDRATE], (state, action) => ({
        ...state,
        ...action.payload.user,
      }))
      
      // 다른유저정보 가져오는 리듀서
      .addCase(loadUserInfo.pending, (state, action) => {
        state.loadUserInfoLoading = true;
        state.loadUserInfoError = null;
        state.loadUserInfoDone = false;
      })
      .addCase(loadUserInfo.fulfilled, (state, action) => {
        state.loadUserInfoLoading = false;
        state.me = action.payload;
        state.loadUserInfoDone = true;
      })
      .addCase(loadUserInfo.rejected, (state, action) => {
        state.loadUserInfoLoading = false;
        state.loadUserInfoError = action.error;
      })
     
      .addDefaultCase((state) => state),
});

이런 코드인데

 // 다른유저정보 가져오는 리듀서
      .addCase(loadUserInfo.pending, (state, action) => {
        state.loadUserInfoLoading = true;
        state.loadUserInfoError = null;
        state.loadUserInfoDone = false;
      })
      .addCase(loadUserInfo.fulfilled, (state, action) => {
        state.loadUserInfoLoading = false;
        state.me = action.payload;
        state.loadUserInfoDone = true;
      })
      .addCase(loadUserInfo.rejected, (state, action) => {
        state.loadUserInfoLoading = false;
        state.loadUserInfoError = action.error;
      })

제가 이것저것 하다가 알게된거 action에 이부분을 전부 주석처리하게 되면 에러가 안난다는 겁니다 그래서 결정적으로 initalstate에 있는 변수들을 변경하는 과정이 브라우저의 정보와 서버의 정보를 다르게만드는 일을 하는것 같은데 혹시 의심가시는거 있으신가요?

react redux node.js express next.js

답변 1

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴이에요.
질문해주신 내용을 보면, Redux Toolkit을 사용한 Server Side Rendering (SSR) 관련 질문이신 것 같은데요. 어떤 오류가 발생하고 있는지 구체적으로 설명해주시면 더 정확한 도움을 드릴 수 있을 것 같아요.
그리고 코드를 보니 loadUserInfo 액션을 호출하는 부분이 보이지 않는데, 해당 액션을 어떻게 정의하셨는지, 그리고 사용하시는 redux 관련 코드에 대해 더 자세한 정보를 주셔야 도움을 드릴 수 있을 것 같아요.

0

i1004gy

pages/about.js

import React from "react";
import { useSelector } from "react-redux";
import Head from "next/head";

import { Avatar, Card } from "antd";
import AppLayout from "../components/AppLayout";
import wrapper from "../store/configureStore";
import { loadUserInfo } from "../reducers/user";

const Profile = () => {
  const { userInfo } = useSelector((state) => state.user);

  return (
    <AppLayout>
      <Head>
        <title>ZeroCho | NodeBird</title>
      </Head>
      {userInfo ? (
        <Card
          actions={[
            <div key="twit">
              짹짹
              <br />
              {userInfo.Posts.length}
            </div>,
            <div key="following">
              팔로잉
              <br />
              {userInfo.Followings.length}
            </div>,
            <div key="follower">
              팔로워
              <br />
              {userInfo.Followers.length}
            </div>,
          ]}
        >
          <Card.Meta
            avatar={<Avatar>{userInfo.nickname[0]}</Avatar>}
            title={userInfo.nickname}
            description="노드버드 매니아"
          />
        </Card>
      ) : null}
    </AppLayout>
  );
};

export const getStaticProps = wrapper.getStaticProps(
  (store) =>
    async ({ req }) => {
      console.log("getStaticProps");
      await store.dispatch(loadUserInfo(1));
    }
);

export default Profile;

이 코드를 보면 아래에

export const getStaticProps = wrapper.getStaticProps(
  (store) =>
    async ({ req }) => {
      console.log("getStaticProps");
      await store.dispatch(loadUserInfo(1));
    }
);

이 부분이 loadUserInfo를 호출하는 부분입니다

0

i1004gy

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import _ from "lodash";
import axios from "axios";
import { HYDRATE } from "next-redux-wrapper";
//Hydrate 즉 Hydration 은서버사이드렌더링을 통한 이미 그려져 불러온 HTML들과 더불어 번들링 된 JS파일들을 클라이언트 단에서 상호작용할 수 있도록 융합되는 과정

export const initialState = {
  loadUserInfoLoading: false, //  유저 정보 가져오는 시도중
  loadUserInfoDone: null, //  유저 정보 가져오는 상태 체크
  loadUserInfoError: false, //  유저 정보 가져오는 것 에러
  
};
export const loadUserInfo = createAsyncThunk(
  "/user/LoadUserInfo",
  async (data) => {
    const response = await axios.get(`/user/${data}`, data);
    return response.data;
  }
);

const userSlice = createSlice({
  name: "user",
  initialState,
  extraReducers: (builder) =>
    builder
      .addCase([HYDRATE], (state, action) => ({
        ...state,
        ...action.payload.user,
      }))
     .addCase(loadMyInfo.pending, (state, action) => {
        state.loadMyInfoLoading = true;
        state.loadMyInfoError = null;
        state.loadMyInfoDone = false;
      })
      .addCase(loadMyInfo.fulfilled, (state, action) => {
        state.loadMyInfoLoading = false;
        state.me = action.payload;
        state.loadMyInfoDone = true;
      })
      .addCase(loadMyInfo.rejected, (state, action) => {
        state.loadMyInfoLoading = false;
        state.loadMyInfoError = action.error;
      })
      .addDefaultCase((state) => state),
});

제가 이상한 action을 가져왔네요 죄송합니다 이게 loadUserInfo 엑션입니다 여기서에서 createSlice부분에 state를 변경하는 코드가 에러가 발생하는 부분인거 같습니다 저곳의 state변경을 주석처리하면 에러가 발생하지 않습니다

Unhandled Runtime Error

Error: Hydration failed because the initial UI does not match what was rendered on the server. See more info here: https://nextjs.org/docs/messages/react-hydration-error

이게 에러 메시지이고

image이게 에러 화면 입니다

넥스트 버젼 질문

0

78

2

로그인시 401 Unauthorized 오류가 뜹니다

0

90

1

무한 스크롤 중 스크롤 튐 현상

0

177

1

특정 페이지 접근을 막고 싶을 때

0

103

2

createGlobalStyle의 위치와 영향범위

0

97

2

인라인 스타일 리렌더링 관련

0

92

2

vsc 에서 npm init 설치시 오류

0

148

2

nextjs 15버전 사용 가능할까요?

0

160

1

화면 새로고침 문의

0

123

1

RTK에서 draft, state 차이가 있나요?

0

154

2

Next 14 사용해도 될까요?

0

452

1

next, node 버전 / 폴더 구조 질문 드립니다.

0

349

1

url 오류 질문있습니다

0

211

1

ssh xxxxx로 우분투에 들어가려니까 port 22: Connection timed out

0

375

1

sudo certbot --nginx 에러

0

1280

2

Minified React error 콘솔에러 (hydrate)

0

470

1

카카오 공유했을 때 이전에 작성했던 글이 나오는 버그

0

247

1

프론트서버 배포 후 EADDRINUSE에러 발생

0

329

1

npm run build 에러

0

519

1

front 서버 npm run build 중에 발생한 에러들

0

383

1

서버 실행하고 브라우저로 들어갔을때 404에러

0

338

2

css 서버사이드 랜더링이 적용되지 않아서 문의 드립니다.

0

289

1

팔로워 3명씩 불러오고 데이터 합쳐주는걸로 바꾸고 서버요청을 무한으로하고있습니다.

0

240

2

해시태그 검색에서 throttle에 관해 질문있습니다.

0

202

1