infinite scrolling

๋”๋ฏธ๋ฐ์ดํ„ฐ์˜ ๋ฉ”์ธํฌ์ŠคํŠธ๋ฅผ ๋นˆ๋ฐฐ์—ด๋กœ ๋งŒ๋“ค์–ด์ค€๋’ค ์•„๋ž˜์™€ ๊ฐ™์ด ํ•ด์ฃผ์„ธ์š”

export const generateDummyPost = (number) => {
  Array(number)
    .fill()
    .map(() => ({
      id: shortId.generate(), //shortid ์‚ฌ์šฉ
      User: {
        id: shortId.generate(), //shortid ์‚ฌ์šฉ
        nickname: faker.name.findName(), //faker์‚ฌ์šฉ
      },
      content: faker.lorem.paragraph(),
      Images: [
        {
          src: faker.image.image(),
        },
      ],
      Comments: [
        {
          User: {
            id: shortid.generate(),
            nickname: faker.name.findName(),
          },
          content: faker.lorem.sentence(),
        },
      ],
    }));
};
initialState.mainPosts = initialState.mainPosts.concat(generateDummyPost(10));
//์ƒํƒœ
  hasMorePost: true,

  loadPostsLoading: false,
  loadPostsDone: false,
  loadPostsError: null,

//์•ก์…˜
export const LOAD_POSTS_REQUEST = "LOAD_POSTS_REQUEST";
export const LOAD_POSTS_SUCCESS = "LOAD_POSTS_SUCCESS";
export const LOAD_POSTS_FAILURE = "LOAD_POSTS_FAILURE";

//๋ฆฌ๋“€์„œ
 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.loadPostsError = null;
        draft.mainPosts = action.data.concat(draft.mainPosts); //์•ž์— ์ถ”๊ฐ€ํ•ด์•ผ ๊ฒŒ์‹œ๊ธ€์ด ์œ„์— ๋‚˜ํƒ€๋‚œ๋‹ค.
        draft.hasMorePost = draft.mainPosts.length < 50;
        break;
      case LOAD_POSTS_FAILURE:
        draft.loadPostsLoading = false;
        draft.loadPostsDone = false;
        draft.loadPostsError = action.error;
        break;
        
        
//์‚ฌ๊ฐ€

function loadPostAPI(data) {
  const response = axios.post("/api/post");
  return response.data;
}

function* loadPost(action) {
  try {
    yield delay(1000);
    const id = shortid.generate();
    // const data = yield call(loadPostAPI, action.data);
    yield put({
      type: LOAD_POSTS_SUCCESS,
      data: data: generateDummyPost(10),
    });
  } catch (e) {
    yield put({
      type: LOAD_POSTS_FAILURE,
      data: e.response.data,
    });
  }
}

function* watchLoadPost() {
  yield takeEvery(LOAD_POSTS_REQUEST, loadPost);
}

export default function* postSaga() {
  yield all([
    fork(watchAddComment),
    fork(watchAddPost),
    fork(watchLoadPost),
    fork(watchRemovePost),
  ]);
}

์ธ๋ฑ์Šค ํŽ˜์ด์ง€๋กœ ๊ฐ€์„œ

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

์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋ ๋•Œ ๋กœ๋“œ๋˜๊ณ , ์Šคํฌ๋กค์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค

function onScroll() {
      console.log(
        window.scrollY,                         //์–ผ๋งˆ๋‚˜ ๋‚ด๋ ธ๋Š”์ง€
        document.documentElement.clientHeight, //ํ™”๋ฉด์— ๋ณด์ด๋Š”๊ธธ์ด
        document.documentElement.scrollHeight //์ด๊ธธ์ด
        //์œ„ 3๊ฐ€์ง€๊ฐ€ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ์ธ๋‹ค 
        // ์ด๊ธธ์ด = ์–ผ๋งˆ๋‚˜ ๋‚ด๋ ธ๋Š”์ง€ + ํ™”๋ฉด์— ๋ณด์ด๋Š”๊ธธ์ด
      );
    }
useEffect(() => {
    function onScroll() {
      console.log(
        window.scrollY,
        document.documentElement.clientHeight,
        document.documentElement.scrollHeight
      );
      if (
        window.scrollY + document.documentElement.clientHeight ===
        document.documentElement.scrollHeight
      ) {
        dispatch({ type: LOAD_POSTS_REQUEST });
      }
    }
    window.addEventListener("scroll", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
      //๋ฆฌํ„ดํ•ด์„œ ๋‹ค์‹œ ์‚ญ์ œ ์•ˆํ•ด์ฃผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ์— ์Œ“์ด๊ฒŒ ๋œ๋‹ค.
    };
  }, []);

react virtualize

๋ชจ๋ฐ”์ผ์—๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์ด ๋ Œํ„ฐ๋˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์žก์•„๋จน๊ฒŒ๋˜๋Š”๋ฐ,

์ธ์Šคํƒ€๊ทธ๋žจ๊ณผ ๊ฐ™์ด ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋งŽ์ด ๋‚˜์˜ค๋Š” ๊ฒƒ๋“ค์€ ํšจ์œจ์ ์œผ๋กœ ํ™”๋ฉด์—๋Š” 3๊ฐœ์”ฉ๋งŒ ๋ณด์—ฌ์ค˜์„œ,

ํ™”๋ฉด์—์„œ๋Š” ๋ž™์ด ์—†์–ด์ง€๋„๋ก ๋„์™€์ค€๋‹ค.

๊ฒ€์ƒ‰ ใ„ฑใ„ฑ!

Last updated