React+Redux)Reduxデータの交換

5772 ワード

無限スクロール(無限スクロール)は、特定の時点でより多くの投稿を呼び出す論理です.
ボタンを押して、中の投稿を次の投稿にしたいです.reduceが使用されているため、firstoreがもたらす次の投稿をミドルウェアで処理し、reducerが現在表示している投稿の数に基づいて次の投稿に置き換えます.
위치) redux > modules > post.js
//action type
const CUT_POST ='CUT_POST';

//action creator
const cutPost = createAction(CUT_POST,(post_list,paging)=>({post_list,paging,}))

//middleware
const getRandomPostFirebase = (start = null, size = 4) => {
  return function (dispatch, getState, { history }) {
    let _paging = getState().log.paging;

    if (_paging.start && !_paging.next) {
      return;
    }

    dispatch(loading(true));
    const postDB = firestore.collection("post");

    let query = postDB.orderBy("insert_dt", "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((d) => {
          let all_data = d.data();

          //['comment_count','contents', ..]
          let post = Object.keys(all_data).reduce(
            (acc, cur) => {
              if (cur.indexOf("user_") !== -1) {
                return {
                  ...acc,
                  user_info: { ...acc.user_info, [cur]: all_data[cur] },
                };
              }
              return { ...acc, [cur]: all_data[cur] };
            },
            { id: d.id, user_info: {} }
          );
          post_list.push(post);
        });
        //4개 넘어 갔으니까 마지막꺼 하나 없애기
        post_list.pop();

        dispatch(cutPost(post_list, paging));
      });
  };
};

//reducer

export default handleActions(
  {
  [CUT_POST]: (state, action) =>
      produce(state, (draft) => {
        draft.post_list=action.payload.post_list;

        draft.post_list = draft.post_list.reduce((acc, cur) => {
          if (acc.findIndex((a) => a.id === cur.id) === -1) {
            return [...acc, cur];
          } else {
            acc[acc.findIndex((a) => a.id === cur.id)] = cur;
            return acc;
          }
        }, []);

        draft.is_loading = false;
        draft.paging = action.payload.paging;
      }),
       },
  initialState
);

//action creator export
const actionCreators = {
  getRandomPostFirebase,
};

export { actionCreators };
このように追加:draft.post_list.push(...action.payload.post_list);pushを拡張演算子としてアレイに挿入します.
元のデータに追加するのではなく、データ自体を置き換えると、上図のようにdraft.post_list = action.payload.post_list;このようにpostリスト自体を変えればいいのです
この値をロードするcomponentからuserSelectorにstateをインポートします.

import { actionCreators as logActions } from "../redux/modules/log";
import { useSelector, useDispatch } from "react-redux";

const Map = (props) => {
  const dispatch = useDispatch();
  const post_list = useSelector((state) => state.log.post_list);
  const paging = useSelector((state) => state.log.paging);

  console.log(post_list);
  
  React.useEffect(() => {
    if (post_list.length < 2) {
      dispatch(logActions.getRandomPostFirebase());
    }
  }, []);

  const renewPostHandler = () => {
    dispatch(logActions.getRandomPostFirebase(paging.next));
  };

  return (
    <div className={classes.wrap}>
          <button className={classes.btn__redirect} onClick={renewPostHandler}>
            <AutorenewIcon />
          </button>
          <div className={classes.logs__wrapper}>
            {post_list &&
              post_list?.map((p, idx) => (
                <MapPost key={p.id + "post_list"} {...p} />
              ))}
          </div>
     </div>
  );
};