티스토리 뷰
[React] Redux-saga , react infinite scroll 구현하기 코드예시
안녕하세요. 이번포스팅에서는 리액트에서, 리덕스사가를 활용해 무한스크롤을 구현하는 방법에 대해 포스팅 하려고합니다.
예시코드를 통해, 이런식으로 구현할 수 있구나 정도로 원리만 파악하시고,
직접 구현하실 때는 , 본인의 코드 스타일에 맞게 구현 하시면 될 것 같아요 !
@ 컴포넌트 코드
// index.js
const Home = () => {
const dispatch = useDispatch();
const { me } = useSelector((state) => state.user);
const { mainPosts, hasMorePosts, loadPostsLoading } = useSelector((state) => state.post);
const imageInput = useRef();
useEffect(() => {
dispatch({
type: LOAD_POSTS_REQUEST,
});
}, []);
// scrollY : 스크롤을 얼마나 내렸는지
// clientHeight : 화면에 보이는 길이
// scrollHeight : 총 길이
// 화면을 끝까지 내렷을 때, scrollY + clientHeight === scrollHeight
useEffect(() => {
function onScroll() {
if (
window.scrollY + document.documentElement.clientHeight >
document.documentElement.scrollHeight - 300
) {
// hasMorePosts는 최대 게시물수를 제한하기 위한 변수입니다.
// 최대 게시물을 제한하지 않으신다면 빼셔도 괜찮아요.
// loadPostsLoading 상태값을 확인해, 로딩중일 경우에 요청을 다시 보내지 않도록 막아주었습니다.
if (hasMorePosts && !loadPostsLoading) {
dispatch({
type: LOAD_POSTS_REQUEST,
});
}
}
}
window.addEventListener('scroll', onScroll);
return () => {
window.removeEventListener('scroll', onScroll);
};
}, [hasMorePosts, loadPostsLoading]);
@ reducer 코드
// reducers/post.js
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 = action.data.concat(draft.mainPosts);
draft.hasMorePosts = draft.mainPosts.length < 50;
break;
case LOAD_POSTS_FAILURE:
draft.loadPostsLoading = false;
draft.loadPostsError = action.error;
break;
default:
break;
}
});
@ saga 코드
// sagas/post.js
// delay를 사용해 비동기 처리를 해주었습니다.
// 실제프로젝트에서 백엔드서버가 있을 경우에는 delay 부분 빼주시고
// 서버에 비동기요청하는 코드로 넣어주시면 될 것 같아요.
// generateDummyPost(n) 은 임의로 만들어 놓은 더미포스트를 n개식 가져오는 함수입니다.
function* loadPosts(action) {
try {
yield delay(1000);
const id = shortId.generate();
yield put({
type: LOAD_POSTS_SUCCESS,
data: generateDummyPost(10),
});
} catch (err) {
yield put({
type: LOAD_POSTS_FAILURE,
data: err.response.data,
});
}
}
// throttle 을 사용해 3초 이내의 요청에 대한 추가적인 응답을 받지 않도록 처리해 주었습니다.
// 단, 백엔드단으로 요청은 계속 날라가니 이부분에 대한 처리도 필요합니다 !! index.js부분 참고@
function* watchLoadPosts() {
yield throttle(3000, LOAD_POSTS_REQUEST, loadPosts);
}
export default function* postSaga() {
yield all([
fork(watchLoadPosts),
]);
}
'개발일기 > REACT' 카테고리의 다른 글
[React] shortid를 사용해 랜덤한 key값 만들기 (0) | 2022.03.08 |
---|---|
[React] pagination Component 만들기 (0) | 2022.03.07 |
[React] createGlobalStyle 사용해서 기존CSS 덮어쓰기. (0) | 2022.03.01 |
[REACT] input[type="file"] 디자인 변경 하는 방법 (0) | 2022.02.27 |
[REACT] NEXTJS 환경 REDUX 초기셋팅 코드예시 (0) | 2022.02.25 |
댓글
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- KEC반영
- TypeScript
- 전기기사 필기
- 실기CBT
- 게더타운
- 산안기 합격률
- TS
- shortid
- 전기공사기사
- 게더타운맵
- 전자기학
- 개더타운
- 전기기사
- 전력공학
- fakerjs
- nextjs
- 산업안전기사
- 전기기기
- 전기기사필기
- React
- 전기기사실기CBT
- gathertown
- cbt
- 전기기사실기단답
- 모두CBT
- zep
- dummydata
- 전기산업기사
- JavaScript
- 산업안전기사 실기
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함