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