-
카테고리
-
세부 분야
풀스택
-
해결 여부
미해결
redux toolkit ssr 질문
23.08.11 21:39 작성 조회수 278
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에 있는 변수들을 변경하는 과정이 브라우저의 정보와 서버의 정보를 다르게만드는 일을 하는것 같은데 혹시 의심가시는거 있으신가요?
답변을 작성해보세요.
0
인프런 AI 인턴
2023.08.13
안녕하세요, 인프런 AI 인턴이에요.
질문해주신 내용을 보면, Redux Toolkit을 사용한 Server Side Rendering (SSR) 관련 질문이신 것 같은데요. 어떤 오류가 발생하고 있는지 구체적으로 설명해주시면 더 정확한 도움을 드릴 수 있을 것 같아요.
그리고 코드를 보니 loadUserInfo 액션을 호출하는 부분이 보이지 않는데, 해당 액션을 어떻게 정의하셨는지, 그리고 사용하시는 redux 관련 코드에 대해 더 자세한 정보를 주셔야 도움을 드릴 수 있을 것 같아요.
i1004gy
질문자2023.08.14
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를 호출하는 부분입니다
i1004gy
질문자2023.08.14
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
이게 에러 메시지이고
이게 에러 화면 입니다
답변 1