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

혜진님의 프로필 이미지

작성한 질문수

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

서버사이드렌더링 준비하기

TypeError: Cannot read properties of undefined (reading 'dispatch')

22.03.10 16:50 작성

·

1.1K

0

질문 없이 알아서 찾고싶은데 생각처럼 진짜 안되네요... 현재 강의 6분30초에서 멈춰있습니다. 에러에 dispatch 가 안된다 하여 또 보니 store 가 undefined 라고 뜹니다. 밑에 저와 똑같은 에러가 발생한 분은 오타셨고 저도 열씸히 오타인지 찾아봤지만 제대로 작성한것 같습니다 configureStore 도 잘 import 했는데 뭐가 문제일까요 서버도 다 재시작해봤는데 안돼용

 

// index.js
 
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";

import AppLayout from "../components/AppLayout";
import PostForm from "../components/PostForm";
import PostCard from "../components/PostCard";
import { LOAD_POSTS_REQUEST } from "../reducers/post";
import { LOAD_USER_REQUEST } from "../reducers/user";
import wrapper from "../store/configureStore";


const Home = () => {
const dispatch = useDispatch();
const { me } = useSelector((state) => state.user);
const { mainPosts, hasMorePosts, loadPostsLoading, retweetError } = useSelector((state) => state.post);

// 자신의 게시글을 리트윗하려 할 때
useEffect(() => {
if(retweetError) {
alert(retweetError);
}
}, [retweetError]);


useEffect(() => {
// 현재 어느 스크롤 위치에 있는지 판단
function onScroll() {
if (
window.scrollY + document.documentElement.clientHeight >
document.documentElement.scrollHeight - 300
) {
if (hasMorePosts && !loadPostsLoading) {
// 로딩이 되고 있을 동안 loadPostsLoading 은 true 이므로 해당 코드 실행되지 x
// 로딩이 끝나고 나서 loadPostsLoading 가 false 가 되면 그때 실행
const lastId = mainPosts[mainPosts.length - 1]?.id // 마지막 게시글 id
// && 대신 optional chaining 활용
// => 게시물이 하나도 없을 경우 undefined.id 에러가 발생할 수 있으므로 ?. 로 방지
dispatch({
type: LOAD_POSTS_REQUEST, // 스크롤 다 내리면 다음 더미데이터 로딩해라
lastId, // 마지막 게시글 id
})
}
}
}
window.addEventListener("scroll", onScroll);
 
return () => {
window.removeEventListener("scroll", onScroll);
};
}, [hasMorePosts, loadPostsLoading, mainPosts]);

return (
<AppLayout>
{me && <PostForm />}
{/* 로그인이 된 상태에서만 포스트를 작성할 수 있음 */}
{mainPosts.map((post) => (
<PostCard key={post.id} post={post} />
))}
</AppLayout>
);
};

 
export const getServerSideProps = wrapper.getServerSideProps((context) => {
context.store.dispatch({
type: LOAD_USER_REQUEST,
});
context.store.dispatch({
type: LOAD_POSTS_REQUEST,
});
// console.log(context);
});
 

export default Home;

 

// configureStore.js

import { createWrapper } from "next-redux-wrapper";
import { applyMiddleware, compose, createStore } from "redux";
import { composeWithDevTools } from 'redux-devtools-extension';
import createSagaMiddleware from 'redux-saga';

import reducer from "../reducers";
import rootSaga from '../sagas';

 
const loggerMiddleware = ({ dispatch, getState }) => (next) => (action) => {
console.log(action) // action 을 실행하기 전에 console.log() 를 한번 실행해주는 미들웨어
return next(action);
}

const configureStore = () => {
const sagaMiddleware = createSagaMiddleware()
// const middlewares = [sagaMiddleware];
const middlewares = [sagaMiddleware, loggerMiddleware];
// enhancer: 리덕스의 기능이 확장된 것
const enhancer = process.env.NODE_ENV === 'production'
? compose(applyMiddleware(...middlewares)) // 배포용
: composeWithDevTools(applyMiddleware(...middlewares)) // 개발용

const store = createStore(reducer, enhancer);
store.sagaTask = sagaMiddleware.run(rootSaga);
return store; // state , reducer 를 포함한 것
};

// next-redux-wrapper 로 만듦
const wrapper = createWrapper(configureStore, {
debug: process.env.NODE_ENV === "development",
});

export default wrapper;


 

답변 4

0

혜진님의 프로필 이미지
혜진
질문자

2022. 03. 10. 18:44

아 버전 문제였군요 제가 지금 7버전인데 대댓글을 ㅅ끝까지 안봤습니다... 아래 답변하신 분이 올린 코드대로 했더니 store 문제가 해결됐는데 이유가 뭔지 알 수 있을까요?

 

 

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

2022. 03. 10. 19:50

비교해보시면 wrapper.getServerSideProps의 모양이 바뀌었습니다. 내부 고차함수가 바뀌었습니다.

0

혜진님의 프로필 이미지
혜진
질문자

2022. 03. 10. 18:27

 

import React from "react";
import Proptypes from "prop-types";
import Head from "next/head";
import "antd/dist/antd.css";

import wrapper from "../store/configureStore";

const NodeBird = ({ Component }) => {
return (
<>
<Head>
<meta charSet="utf-8" />
<title>NodeBird</title>
</Head>
<Component />
</>
);
};

NodeBird.propTypes = {
Component: Proptypes.elementType.isRequired,
};

export default wrapper.withRedux(NodeBird);

_app.js 강의 코드와 똑같습니다

 

0

혜진님의 프로필 이미지
혜진
질문자

2022. 03. 10. 17:42

그래서 제가 이미 store 도 확인해봤는데 원본과 다를게 없는 코드였어서,,  configureStore 파일 말고 더 확인할 곳이 있을까요,, 복붙해서 실행해밨는데도 똑같아여

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

2022. 03. 10. 17:45

_app.js쪽 봐보세요.

0

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

2022. 03. 10. 17:10

이건 store 연결이 제대로 안 된거라고밖에는 보여지지 않습니다. store쪽에 문제가 있을 겁니다.

혜진님의 프로필 이미지

작성한 질문수

질문하기