강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của giraff59385
giraff59385

câu hỏi đã được viết

[Renewal] Tạo NodeBird SNS bằng React

Tải bài đăng

LOAD_POSTS_REQUEST가 무한정 일어나요.,

Viết

·

744

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시간째 헤매고 있습니다

도와주세요

무한로딩LOAD_POSTS_REQUESTnodejsexpress무한react무한요청프론트reduxNext.js

Câu trả lời 3

0

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

    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라서 실행되는게 아닌가 싶기도 합니다.
giraff59385님의 프로필 이미지
giraff59385
Người đặt câu hỏi

hasMorePosts는 계속 true 입니다.

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

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

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

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

giraff59385님의 프로필 이미지
giraff59385
Người đặt câu hỏi

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

일단 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

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

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

0

giraff59385님의 프로필 이미지
giraff59385
Người đặt câu hỏi

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

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

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

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

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

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

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

이 부분 오타는 수정하신거죠?
giraff59385님의 프로필 이미지
giraff59385
Người đặt câu hỏi

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

0

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

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

Hình ảnh hồ sơ của giraff59385
giraff59385

câu hỏi đã được viết

Đặt câu hỏi