inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

React로 NodeBird SNS 만들기

강의 깃허브 코드에 버그가 있습니다

214

데구리

작성한 질문수 9

0

어제 인피니트 스크롤링에서 버그가 발생한다고 글을 올렸습니다. 확인해보니 강의 코드에도, nodebird.com 에도 동일한 버그가 존재하지만 두 가지 버그가 맞물려 그런 현상이 일어나지 않는 것 처럼 보입니다.

우선 getInitialProps에서 한 번, onScroll 이벤트에서 한 번, 이렇게 총 두 번씩 request - request - success - success 하여 mainPosts에 중복된 데이터가 들어가는 현상은 사이트 내 스크롤바가 어느정도 아래로 내려와있는 상태에서, 포스트들을 로드하는 다른 페이지(index, hashtag, profile)로 이동했을 때, 해당 포스트들을 로딩하는 리퀘스트를 saga에서 throttle로 받게끔 한 경우 생깁니다.

노드버드 사이트 내에서는 버그를 재현하기가 굉장히 애매합니다.

노드버드 코드에서 throttle을 적용한 곳이 watchLoadMainPosts() 밖에 없습니다. 근데 index 페이지로 이동하는 버튼은 최상단에 있습니다. 그러니 스크롤바가 내려간 상태에서 인덱스 페이지로 이동하는 방법은  다른 페이지에서 스크롤을 쭉 내린 후 뒤로가기를 통해 들어가는 방법인데요, 이게 또 브라우저에 달린 뒤로가기 버튼으로는 발생하지 않고 마우스에 달린 뒤로가기 버튼이나 마우스 제스쳐를 통한 뒤로가기시에만 발생합니다ㅜㅜ..

혹시 테스트 해보실 예정이라면 index 페이지 대신 watchLoadHashtagPosts() 코드를 throttle로 수정한 뒤에, 메인 페이지 스크롤을 쭉 내린 후 보이는 아무 해시태그나 눌러서 그 페이지로 들어가 확인하는게 더 편할 것 같습니다.

아무튼 저렇게 뒤로가기를 해서 메인 페이지로 돌아가게 되면 노드버드 페이지 콘솔에 다음과 같은 에러 로그가 찍힙니다.

이 부분은

 https://github.com/ZeroCho/react-nodebird/blob/master/ch8/front/pages/index.js

해당 코드의 16번째 줄에서 mainPosts가 비어있는지 확인하지 않아 mainPosts가 비어있는 경우, undefined.id에 접근을 해서 나는 에러입니다.

페이지로 들어갈 때 getInitialProps에서 한 번, onScroll 이벤트에서 한 번씩 디스패치를 하게 되는데, getInitialProps에서 디스패치된 리퀘스트가 리덕스 state의 mainPosts를 빈 배열로 만들고, 그 상황에서 16번째 줄이 실행되어 위에 첨부한 에러가 발생합니다.

따라서 nodebird.com 내에선 해당 에러가 catch되어 아랫부분의 dispatch가 실행되지 않아 같은 포스트들이 두 번 로드되는 상황이 일어나지 않습니다. 결과적으로 사이트 내에선 버그가 없는 것 처럼 보익 ㄱㅔ됩니다.

실제로 제로초님 깃허브 코드를 그대로 받아 undefined 버그를 해결해 테스트해보면 중복된 데이터가 들어오는 현상이 일어납니다.

중복 데이터 버그를 해결하여 공지로 올려주시거나 강의에서 throttle 쓰는 내용을 제거하는게 좋을 것 같습니다.

감사합니다.

react javascript

답변 1

0

제로초(조현영)

저는 다음과 같이 useEffect, useCallback의 배열에 dependencies를 정확히 기재하는 것으로 중복데이터 버그를 해결하였습니다.
데구리님도 되시나요?

import
React, { useCallback, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { LOAD_HASHTAG_POSTS_REQUEST } from '../reducers/post';
import PostCard from '../containers/PostCard';

const Hashtag = ({ tag }) => {
const dispatch = useDispatch();

const { mainPosts, hasMorePost } = useSelector(state => state.post);

const onScroll = useCallback(() => {
if (window.scrollY + document.documentElement.clientHeight > document.documentElement.scrollHeight - 300) {
if (hasMorePost) {
dispatch({
type: LOAD_HASHTAG_POSTS_REQUEST,
lastId: mainPosts[mainPosts.length - 1] && mainPosts[mainPosts.length - 1].id,
data: tag,
});
}
}
}, [hasMorePost, mainPosts.length, tag]);

useEffect(() => {
window.addEventListener('scroll', onScroll);
return () => {
window.removeEventListener('scroll', onScroll);
};
}, [mainPosts.length, hasMorePost, tag]);

return (
<div>
{mainPosts.map(c => (
<PostCard key={c.id} post={c} />
))}
</div>
);
};

Hashtag.propTypes = {
tag: PropTypes.string.isRequired,
};

Hashtag.getInitialProps = async (context) => {
const { tag } = context.query;
console.log('hashtag getInitialProps', tag);
context.store.dispatch({
type: LOAD_HASHTAG_POSTS_REQUEST,
data: tag,
});
return { tag };
};

export default Hashtag;

next 10 이상에서는 redux dev tool 구동이 안되나요?

0

272

1

세션 갱신 문의 건

0

483

7

배포 진행 후 Highlight updates components render 표시

0

445

1

똑같은 기능을 하는 테이블

0

447

4

관계형

0

312

2

프론트 서버를 이용하지 않는경우

1

299

3

인피니트 스크롤링 사용시 오류

0

278

0

계속 이런에러가 떠서 해결하기는 했는데 어떤 의미인지 모르겠습니다.

0

434

2

req.user가 언제 생성되나요??

0

330

2

Cannot read property 'id' of null 에러

0

333

1

리트윗한 게시글 불러오는 sequelize

0

252

1

result.data에서 images인 이유

0

281

2

takeLatest에 대한 질문입니다.

1

342

2

프론트에서 express를 사용하지 않을때 동적라우팅

0

501

6

getInitialProps가 클라이언트에서 수행되는 이유?

0

258

1

리로드하면 팔로우 언팔로우 값이 초기화 되는 문제입니다.

0

445

2

스타일드 컴포넌트와 className을 통한 스타일 적용의 차이에 대해 궁금합니다

0

585

2

할인 쿠폰 사용이 안되는되요 (848-f9af83f183e3)

0

365

1

nodejs mvc 패턴

0

975

4

사용하고 보니, 람다 구성이 궁금합니다!

0

266

1

제로초님

0

445

1

새로고침 로그인 풀림 문제.

0

247

1

안녕하세요. 강의 너무 감사합니다

0

157

1

제로초님

0

170

1