代码之家  ›  专栏  ›  技术社区  ›  Hamed Ezati

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

  •  1
  • Hamed Ezati  · 技术社区  · 2 年前

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

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

    我想知道,为什么API调用的结果附加了Redux而不是replace?换句话说,我如何每次在页面加载时清理Redux?预期结果是页面上总是有10条(文章) Article 当我打开它的时候。


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

    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);
    

    还有,这里是 文章 第页:

    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;
    
    1 回复  |  直到 2 年前
        1
  •  0
  •   emre-ozgun    2 年前
    case ReducerTypes.GET_ALL_POSTS:
                return {
                    ...state,
                    posts: {
                        items: action.payload.items,
                        pagination: action.payload.pagination
                    }
                };
    

    试着忽略这个。concat()