류림스 공간

[항해99 30일차] 2022.04.05 TIL /무한 스크롤 알림기능 본문

TIL/2022 TIL

[항해99 30일차] 2022.04.05 TIL /무한 스크롤 알림기능

ryurim 2022. 4. 6. 00:36
반응형

<오늘 할 일>

 

1. 4주차 강의 다 듣기

 

난이도 급상승으로 ..

강의내용을 그대로 따라해도 막 오류나고 그런다.ㅠㅠ

흑흑

 

무한 스크롤 만들 준비

post.js 덕스구조에 아래 내용을 추가해준다.

//액션타입
const LOADING ="LOADING";
//액션 생성
const setPost =createAction(SET_POST,(post_list, paging)=>({post_list,paging}));
const loading =createAction(LOADING,(is_loading)=>({is_loading}));
//초기값
const initialState ={
    list: [],
    paging: {start: null, next: null, size: 3},
    is_loading: false,
};
//리듀서
[SET_POST] : (state, action) => produce(state, (draft)=>{
            draft.list.push(...action.payload.post_list)
            draft.paging =action.payload.paging;
            draft.is_loading =false;
        }),
        
[LOADING]: (state, action) => produce(state, (draft) => {
        draft.is_loading = action.payload.is_loading;
      }),

미들웨어

const getPostFB =(start=null, size=3)=>{
    return function(dispatch,getState,{history}){
        let _paging =getState().post.paging;

        if(_paging.start && !_paging.next){//만약 이 페이징에서 스타트에 값이 있어 그런데 페이징에 넥스트 값이 없어 그러면 바로 돌아가
            return
        };

        dispatch(loading(true))  //무한스크롤
        const postDB =firestore.collection('post');
         //무한스크롤
        let query =postDB.orderBy('insert_dt',"desc"); //desc면 역순으로 가져오기

        if(start){
            query= query.startAt(start);
        }
        query
        .limit(size + 1).get().then(docs =>{
            let post_list =[];
            let paging ={
                start: docs.docs[0],
                next: docs.docs.length === size +1 ? docs.docs[docs.docs.length -1] : null,
                size: size,
            }
            docs.forEach((doc)=>{
              let _post = doc.data();
             
               
              let post = Object.keys(_post).reduce((acc,cur)=>{
                if(cur.indexOf("user_")!==-1) { //user_가 포함이 된다면
                    return{
                        ...acc,
                        user_info:{...acc.user_info,[cur]:_post[cur]},
                    };
                }
                return {...acc, [cur]: _post[cur]};
              },{id: doc.id,user_info:{}});

            post_list.push(post);
                
            })
            post_list.pop(); //마지막 친구 없애기
            dispatch(setPost(post_list, paging))
        });
    };
};

오우 ...여기서 끝이 아니었당.

PostList.js

 //데이터 가져오기
 const is_loading =useSelector((state)=> state.post.is_loading);
 const paging =useSelector((state)=> state.post.paging);
<button onClick={()=>{
                        dispatch(postActions.getPostFB(paging.next))
                    }}>더보기</button>

더보기 버튼 임시로 만들어서 적용!

이렇게 하니까 더보기 버튼 클릭하면, 목록을 잘 가져온당.

 

 

무한스크롤 컴포넌트

import React from "react";
import _ from "lodash";

const InfinScroll =(props)=>{

    const {children,callNext,is_next, loading}=props;
    
    const _handleScroll = _.throttle(()=>{

        callNext();
    },300);

    const handleScroll = React.useCallback(_handleScroll,[loading]);

    React.useEffect(()=>{

        if(loading){
            return
        }

        if(is_next){
            window.addEventListener("scroll",handleScroll);
        }else{
            window.removeEventListener("scroll",handleScroll)
        }
        

        return ()=> window.removeEventListener("scroll",handleScroll);
    }, [is_next, loading])
    return (
        <React.Fragment>
            {children}
        </React.Fragment>
    )
};
InfinScroll.defaultProps ={
    children:null,
    callNext: ()=>{},
    is_next: false,
    loading:false,
}
export default InfinScroll;

👉 [브라우저 창 크기 알아보기]

 

페이지 끝에 닿았는 지 알려면 어떻게 할까? → 스크롤할 수 있는 영역이 얼마나 남았나 계산을 해보면 됨.

계산을 하려면, 웹 페이지 전체 크기도 알아야하고 얼마나 스크롤했는 지도 알아야됨

window.innerHeight은 가시적으로 보이는 브라우저 창 높이(메뉴바 툴바 제외한 크기!)

document.body.scrollHeight는 스크롤할 수 있는 높이(눈에 안보이는 영역도 포함!)

document의 scrollTop은 스크롤이 얼마나 움직였나 알려주는 값

 

화면 크기 관련 내용 더 알아보기→ (링크)

 

무한스크롤 추가코드

 

 const _handleScroll = _.throttle(()=>{
        if(loading){
            return
        };

        const {innerHeight} = window;
        const {scrollHeight} = document.body;

        const scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;

        if(scrollHeight-innerHeight-scrollTop < 200){
            callNext();
        }
    },300);
 callNext ={()=>{
                            dispatch(postActions.getPostFB(paging.next));
                        }}

이렇게 하면 스크롤 내렸을 때 잘 뜬다.

 

 

무한스크롤 + 게시글 올리기

하하하하하ㅏㅎ하하하하ㅏ

어렵구나~~~~

 

헉 과제에...는 강의에 나오지 않는 내용도 있었다.

알림 뱃지 기능은 미뤄두고,,,

레이아웃 선택하는거부터 구현해야되겠다.

 

드디어 구현했다...짱나게 에러떠서 당황했지만,

나의 오타였다...

오타 발견하는 게 제일 어려운 거 같다.

 

그리고 강의 자료에 있는 yarn 패키지들 그냥 복붙하면 에러난다 ㅡㅡ

공식 사이트에서 최신 버전으로..설치해줘야 에러가 안난다.

 

ㅎ..이거때문에 시간을 많이 잡아먹었ㄷ...ㅏ

 

notiDB.on('value',(snapshot)=>{ //값이 바뀌었을 때
            console.log(notiDB, snapshot.val())
        });

강의 4-11 따라하는데 나만 snapshot.val() 값이 null 나와서 당황했는데...

ㅋㅋㅋㅋㅋㅋ저기 노티 아래에 값을 uid로 해줘야된당.ㅠㅠㅠㅠㅠㅠ

난 이상한 영어로 해서 안되었던 듯 하다...

 

이렇게 알림기능까지 완료

내일은 강의 마무리해서 듣고 ..재빨리 한번 더 들어야겠다

하나도 이해가 가지 않는다.

코드도 너ㅓㅓㅓ무 복잡하고,,,,

이리갔다 저리갔다....

공부하기에 시간이 넘 부족하다..

 

파이어 베이스로 배포하는데 

; 하나 빠뜨려서...에러떠서 배포도 늦게했당..ㅎ

 

<내일 할 일> 

1. 5-3부터 강의듣기

2. 다시 1주차부터 차근차근 강의 듣기

3. 과제 제출

728x90
반응형
Comments