为什么项目附加到 redux 而不是替换?

Why items appends to the redux rather than replace?

我是 Reactjs 的新手。我遇到的问题:

第一次加载文章页面时,一切正常,显示了 10 篇文章。当我点击浏览器后退按钮,然后我第二次进入文章页面时,文章列表将被复制(所以,它将是 20 篇文章)。如果我再这样做,那就是30篇等等..

我想知道,为什么 API 调用的结果会附加到 Redux 而不是替换?换句话说,我怎样才能每次都在页面加载时清理 Redux?预期结果是当我打开页面 Article 时总是看到 10 项(文章)。


这是主页中元素(用于导航到文章列表)的简化:

import Pages from "Constants/Pages";

const Component = () => {

    const history = useHistory();
    const navigateWithToken = (page) => {
        history.push(page);
      }
    };
    
    return (
        <div className="d-flex align-items-center flex-column py-1 ">
          <div
            className="main-footer-btn-article"
            onClick={() => navigateWithToken(Pages.Articles)}
          ></div>
          <span className="main-footer-btn-text">Articles</span>
        </div>
    )
};

export const ArticlesBtn = memo(Component);

此外,这是 Article 页面:

import { memo, useEffect } from "react";
import { useHistory } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";

import PostItems from "SharedComponents/PostItems";
import { getAllPosts } from "Redux/Actions";
import Pages from "Constants/Pages";

const Page = () => {
  const posts = useSelector((state) => state?.articles?.posts?.items);
  const dispatch = useDispatch();
  const { push } = useHistory();
  useEffect(() => {
    dispatch(getAllPosts());
  }, []);

  const onClickPost = (item) => {
    push({
      pathname: Pages.SingleArticle,
      state: {
        postId: item.id,
        title: item.subject,
        is_saved: item.is_saved,
      },
    });
  };

  return (
    <div className="full-height overflow-auto">
      { 
        posts?.map((item, index) => {
          return (
            <PostItems
              {...item}
              key={item.id}
              index={index}
              onClickPost={() => onClickPost(item)}
            />
          );
        })
      }
    </div>
  );
};

export default memo(Page);

这里还有 API 调用:

const getAllPosts = (page = 1) => {
  return async (dispatch: ReduxDispatch) => {
    //"posts?for=for_website"
    dispatch(toggleLoading(true));
    try {
      const { data } = await axios({
        method: "GET",
        url: "posts?for=for_mobile",
        params: { page: page },
      });
      const items = data?.data?.data;
      const pagination = {
        current_page: data.data.current_page,
        last_page: data.data.last_page,
      };
      dispatch(
        dispatchItemToRedux({
          type: ReducerTypes.GET_ALL_POSTS,
          payload: {
            items,
            pagination,
          },
        })
      );
    } catch (err) {
      return Promise.reject(err);
    } finally {
      dispatch(toggleLoading(false));
    }
  };
};

此外,这里是减速器:

import ReducerTypes from "Redux/Types/ReducerTypes";

const INITIAL_STATE = {
    posts: {
        items: [],
        pagination: {}
    },
    singlePost: {
        id: null,
        subject: null,
        caption: null,
        deep_link: null,
        short_link: null,
        total_comments: null,
        total_likes: null,
        total_views: null,
        created: null,
        medias: null,
        likes: [] 
    },
    postComments: []
};

function articleReducer(state = INITIAL_STATE, action) {
    switch (action.type) {
        case ReducerTypes.GET_ALL_POSTS:
            return {
                ...state,
                posts: {
                    items: state.posts.items.concat(action.payload.items),
                    pagination: action.payload.pagination
                }
            };
        case ReducerTypes.GET_SINGLE_POST:
            return {
                ...state,
                singlePost: action.payload
            };
        case ReducerTypes.GET_POST_COMMENTS:
            return {
                ...state,
                postComments: action.payload
            };
        case ReducerTypes.GET_POST_LIKES:
            return {
                ...state,
                singlePost: {
                    ...state.singlePost,
                    likes: action.payload
                }
            };
        default:
            return state;
    };
};
export default articleReducer;
case ReducerTypes.GET_ALL_POSTS:
            return {
                ...state,
                posts: {
                    items: action.payload.items,
                    pagination: action.payload.pagination
                }
            };

尝试省略 .concat()