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

기본은하고싶다님의 프로필 이미지
기본은하고싶다

작성한 질문수

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

게시글 불러오기

LOAD_POSTS_REQUEST가 무한정 일어나요.,

작성

·

630

0

 
 
보시다 시피 GET /posts 304 에러로 인해 정상 작동하지 않습니다.
사진상으로는 멈춰있지만 무시무시하게 많은 에러가 제 신성한 VSC 터미널창을 도배하고 있습니다.
 
처음엔 REQUEST - SUCCESS를 번갈아 보내는 모습을 보고, 'page/index.js'에서 요청을 보내는 클라이언트의 잘못이라고 생각했습니다.
REQUEST를 무한정 보내고 있으니 보내는 쪽의 문제일 거라고요..

 

front/page/index.js

...
...
import { LOAD_POSTS_REQUEST } from '../reducerss/post';
import { LOAD_USER_REQUEST } from '../reducers/user';

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

    useEffect(() =>{
        dispatch({
            type: LOAD_USER_REQUEST,
        });
        dispatch({
            type: LOAD_POSTS_REQUEST,
        })
    }, []);

    const [ref, inView] = useInView();
    // useEffect(() => {}, []) : 뒤에 빈배열을 넣을 경우.componentDidMount()같은 효과를 줄 수 있다.

    useEffect(() => {
        if (inView && hasMorePosts && !loadPostsLoading) {
            const lastId = mainPosts[mainPosts.length - 1]?.id;
            dispatch({
                type: LOAD_POSTS_REQUEST,
                lastId,
            });
        }
    }, [inView, hasMorePosts, loadPostsLoading, mainPosts]);

    return (
        <AppLayout>
            {me && <PostForm />}
            {mainPosts.map(post => (
                <PostCard key={post.id} post={post} />
            ))}
            .......
            .......
        </AppLayout>
    );
};

export default Home;

그런데 딱히 특이사항이 발견되지 않아서 front/sagas와 front/reducers 쪽을 보았습니다.

front/sagas

import {
    all,
    delay,
    fork,
    put,
    call,
    takeLatest,
    throttle,
} from 'redux-saga/effects';
import axios from 'axios';
import {
    ......
    LOAD_POSTS_REQUEST,
    LOAD_POSTS_SUCCESS,
    LOAD_POSTS_FAILURE,
} from '../reducers/post';


function loadPostsAPI(data) {
    //실제로 서버에 요청을 보냄
    return axios.get('/posts', data);
}

function* loadPosts(action) {
    try {
        const result = yield call(loadPostsAPI, action.data);
        yield put({
            type: LOAD_POSTS_SUCCESS,
            data: result.data, // data에 게시글들 배열 -> 이것은 reducer로 간다
        });
    } catch (err) {
        yield put({
            type: LOAD_POSTS_FAILURE,
            data: err.response.data,
        });
    }
};
....
function* watchLoadPosts() {
    yield takeLatest(LOAD_POSTS_REQUEST, loadPosts);
}
....
export default function* postSaga() {
    yield all([
        fork(watchAddPost),
        fork(watchLoadPosts),
        fork(watchRemovePost),
        fork(watchAddComment),
    ]);
}

 

front/reducers

const reducer = (state = initialState, action) =>
    produce(state, draft => {
        switch (action.type) {
            case LOAD_POSTS_REQUEST:
                draft.loadPostsLoading = true;
                draft.loadPostsDone = false;
                draft.loadPostsError = null;
                break;
            case LOAD_POSTS_SUCCESS:
                draft.loadPostsLoading = false;
                draft.loadPostsDone = true;
                draft.mainPosts = draft.mainPosts.concat(action.data);
                draft.loadPostsError = null;
                draft.hasMorePosts = draft.mainPosts.length < 50;
                break;
            case LOAD_POSTS_FAILURE:
                draft.loadPostsLoading = false;
                draft.loadPostsError = action.error;
                break;

304 에러로 보아 서버 쪽 문제일 수도 있어서 라우터 쪽도보았습니다.

const express = require('express');

const { Post, Image, User, Comment } = require('../models');

const router = express.Router();

router.get('/', async (req, res, next) => { // GET /posts
    try {
        const posts = await Post.findAll({
            limit: 10,
            order: [['createdAt', 'DESC']],
            include: [{
                model: User,
            }, {
                model: Image,
            }, {
                model: Comment,
            }],
        });
        res.status(200).json(posts);
    } catch (error) {
        console.error(error);
        next(error);
    }
});

module.exports = router;

 

 

 

 

어느쪽 문제인지 사실 잘 모르겠습니다.
저런식으로 무한 로딩 에러가 난다면 어디에서 에러를 찾아야 하나요? 제가 생각하기엔 프론트였는데 예상이 빗나가서 2시간째 헤매고 있습니다

도와주세요

답변 3

0

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

    useEffect(() => {
        if (inView && hasMorePosts && !loadPostsLoading) {
            const lastId = mainPosts[mainPosts.length - 1]?.id;
            dispatch({
                type: LOAD_POSTS_REQUEST,
                lastId,
            });
        }
    }, [inView, hasMorePosts, loadPostsLoading, mainPosts]);

이 부분이 의심되는데 콘솔로그 넣어보시겠어요? 뭔가 hasMorePOsts나 !loadPostsLoading이 안 바뀌어서
ㅖ속 true라서 실행되는게 아닌가 싶기도 합니다.

hasMorePosts는 계속 true 입니다.

loadPostsLoading은 두번 false를 찍다가 두번 true 찍는 걸 반복합니다

reducers / post 쪽을 봐야할까요??

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

hasMorePosts가 왜 계속 true일까요? 그 부분을 찾아보세요.

질문 너무 잘 받아주셔서 몸둘바를 모르겠어요 !! 정말 감사드려요

일단 hasMorePosts가 계속 true가 나오는 부분을 생각해보니
LOAD_POSTS_SUCCESS 이후 hasMorePosts 값을 정하는 부분에 오류가 있어서

계속 true가 나오는 것 같다고 추측하고 reducers/post.js로 가서 

                draft.hasMorePosts = draft.mainPosts.length < 50;

이 부분을

                draft.hasMorePosts = action.data.length === 10;

이렇게 고치니까 해결이 되었구요.... 
아마 mainPosts의 더미데이터를 지우고 나서 바로 돌리니까 (강의내용을 빼먹었는지..뭔지.. ㅠ)
mainPosts에 값이 없으니 당연히 length < 50이 계속 true가 나오는 것이었어요..

무한 로딩은 더이상 이루어지지 않았습니다 !!

마지막으로 딱 하나만 질문 드려보자면...

얼추 해결 후 돌려보니까 아무 게시글이 뜨지 않고 

sagas/post.js에서 GET /posts 의 result 찍어봤는데

function loadPostsAPI(data) {
    //실제로 서버에 요청을 보냄
    console.log('/posts로 GET요청:: 데이터와 함꼐->', data);
    return axios.get('/posts', data);
}

function* loadPosts(action) {
    console.log('Sagas:: loadPosts 실행 중', action.data);
    try {
        const result = yield call(loadPostsAPI, action.data);
        // yield delay(1000);
        console.log('loadPost 완료::', result);  <---- 요 부분... 요부분 찍으니 Array(0)
        yield put({
            type: LOAD_POSTS_SUCCESS,
            data: result.data, // data에 게시글들 배열 -> 이것은 reducer로 간다
        });


Array(0)으로 나온거면

아직 DB쪽에 데이터가 없어서 아무 게시글도 안 띄운걸로 봐도 무방하겠지요? 괜히 불안해서요

back terminal 에서 계속 304 에러가 뜨는 것도 같은 선상이겠죠? (DB에 데이터 없음?)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

다시 한 번 바쁘신 와중에 질문 받아주셔서 감사합니다 m(_ _ )m

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

네 일단 304는 에러가 아니고 200이랑 같은 겁니다. 성공입니다. 빈 배열이 나오는 이유는 데이터가 디비에 없는 게 맞을겁니다.

0

빠른 답변 감사합니다! 아직 문제 미해결 상태..입니다

질문을 졸면서 적어서 오타가..ㅋㅋ 죄송합니다... 제 전체 폴더 / 파일명입니다..

이번 회차 강의 이전까지는 오타로 인한 오류를 발견한 적이 없어서 더 아리송한데요..

일단 reducers 나머지 부분 올려보겠습니다.

이상한 부분 보이면 말씀해주세요

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

import { LOAD_POSTS_REQUEST } from '../reducerss/post';

이 부분 오타는 수정하신거죠?

넵 저기는 복붙하다가 생긴 오타에요.. reducers/post라고 정확히 적어두었습니다..

0

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

파일명부터 오타들이 많은데요. 오타일 가능성이 높습니다. reducers action코드도 보고싶네요.

기본은하고싶다님의 프로필 이미지
기본은하고싶다

작성한 질문수

질문하기