Sfoglia il codice sorgente

trim dispatches| before SAGA

ilya_shyian 2 anni fa
parent
commit
828f91571d

+ 12 - 0
src/actions/actionCatByIdFull.js

@@ -0,0 +1,12 @@
+import { actionFeedClear, actionPromiseClear } from "../reducers";
+import { actionFeedCategoryGoods } from "../reducers/feedReducer";
+import { actionCatById } from "./actionCatById";
+
+export const actionCatByIdFull =
+    ({ _id, orderBy }) =>
+    async (dispatch, getState) => {
+        const category = await dispatch(actionCatById({ _id }));
+        dispatch(actionFeedClear());
+        dispatch(actionPromiseClear("feedCategoryGoods"));
+        dispatch(actionFeedCategoryGoods({ category, orderBy, skip: 0 }));
+    };

+ 8 - 0
src/actions/actionCatByIdFullClear.js

@@ -0,0 +1,8 @@
+import { actionFeedClear, actionPromiseClear } from "../reducers";
+import { actionCatById } from "./actionCatById";
+
+export const actionCatByIdFullClear = () => async (dispatch, getState) => {
+    dispatch(actionPromiseClear("catById"));
+    dispatch(actionFeedClear());
+    dispatch(actionPromiseClear("feedCategoryGoods"));
+};

+ 1 - 1
src/components/GoodsPage/index.js

@@ -50,5 +50,5 @@ const GoodsPage = ({ category = {}, goods = [] }) => {
     );
 };
 
-const CGoodsPage = connect((state) => ({ category: state?.promise?.catById?.payload || [] }))(GoodsPage);
+const CGoodsPage = connect((state) => ({ category: state?.promise?.catById?.payload || {}, goods: state?.feed?.payload || [] }))(GoodsPage);
 export { GoodsPage, CGoodsPage };

+ 47 - 0
src/components/LayoutPage/GoodsPageContainer.js

@@ -0,0 +1,47 @@
+import { connect } from "react-redux";
+import { useEffect } from "react";
+import { useDispatch } from "react-redux";
+import { useParams, useSearchParams } from "react-router-dom";
+import { actionCatByIdFull } from "../../actions/actionCatByIdFull";
+import { actionCatByIdFullClear } from "../../actions/actionCatByIdFullClear";
+import { actionFeedCategoryGoods } from "../../reducers/feedReducer";
+import { InfScroll } from "../common/InfScroll";
+import { CGoodsPage } from "../GoodsPage";
+
+const GoodsPageContainer = ({ feed, goods, promiseStatus, onLoad, onUnmount, onScroll, category }) => {
+    const params = useParams();
+    const [searchParams] = useSearchParams();
+    const orderBy = searchParams.get("orderBy") || "_id";
+
+    useEffect(() => {
+        onLoad({ orderBy, _id: params._id });
+
+        return () => {
+            onUnmount();
+        };
+    }, [params._id, orderBy]);
+
+    return (
+        <InfScroll
+            items={goods}
+            component={CGoodsPage}
+            promiseStatus={promiseStatus}
+            onScroll={() => onScroll({ feed, orderBy, category })}
+            orderBy={orderBy}
+        />
+    );
+};
+
+export const CAdminGoodsPageContainer = connect(
+    (state) => ({
+        goods: state.promise?.feedCategoryGoods?.payload || [],
+        feed: state.feed?.payload || [],
+        category: state.promise?.catById?.payload || null,
+        promiseStatus: state.promise?.feedCategoryGoods?.status || null,
+    }),
+    {
+        onUnmount: () => actionCatByIdFullClear(),
+        onLoad: ({ orderBy, _id }) => actionCatByIdFull({ orderBy, _id }),
+        onScroll: ({ feed, orderBy, category }) => actionFeedCategoryGoods({ skip: feed.length || 0, orderBy, category }),
+    }
+)(GoodsPageContainer);

+ 44 - 0
src/components/LayoutPage/GoodsSearchPageContainer.js

@@ -0,0 +1,44 @@
+import { useEffect } from "react";
+import { connect } from "react-redux";
+import { useSearchParams } from "react-router-dom";
+import { actionGoodsSearchPage } from "../../actions/actionGoodsSearchPage";
+import { actionGoodsSearchPageClear } from "../../actions/actionGoodsSearchPageClear";
+import { actionFeedGoodsFind } from "../../reducers";
+import { InfScroll } from "../common/InfScroll";
+import { CGoodsPage } from "../GoodsPage";
+
+const GoodsSearchPageContainer = ({ feed, goods, promiseStatus, onLoad, onUnmount, onScroll }) => {
+    const [searchParams] = useSearchParams();
+    const orderBy = searchParams.get("orderBy") || "_id";
+    const text = searchParams.get("text") || "";
+
+    useEffect(() => {
+        onLoad({ orderBy, text });
+        return () => {
+            onUnmount();
+        };
+    }, [orderBy, text]);
+
+    return (
+        <InfScroll
+            items={goods}
+            component={CGoodsPage}
+            promiseStatus={promiseStatus}
+            onScroll={() => onScroll({ feed, orderBy, text })}
+            orderBy={orderBy}
+        />
+    );
+};
+
+export const CAdminGoodsSearchPageContainer = connect(
+    (state) => ({
+        goods: state.promise?.feedGoodsFind?.payload || [],
+        feed: state.feed?.payload || [],
+        promiseStatus: state.promise?.feedGoodsFind?.status || null,
+    }),
+    {
+        onUnmount: () => actionGoodsSearchPageClear(),
+        onLoad: ({ orderBy, text }) => actionGoodsSearchPage({ orderBy, text }),
+        onScroll: ({ feed, orderBy, text }) => actionFeedGoodsFind({ text, skip: feed?.length || 0, orderBy }),
+    }
+)(GoodsSearchPageContainer);

+ 40 - 115
src/components/LayoutPage/index.js

@@ -1,150 +1,76 @@
 import { Box, Grid } from "@mui/material";
 import { useEffect } from "react";
-import { connect, useDispatch, useSelector } from "react-redux";
-import { Navigate, Route, Routes, useLocation, useParams, useSearchParams } from "react-router-dom";
-import { actionCatById } from "../../actions/actionCatById";
+import { connect } from "react-redux";
+import { Navigate, Route, Routes, useLocation, useParams } from "react-router-dom";
 import { actionGoodById } from "../../actions/actionGoodById";
-import { actionGoodsFind } from "../../actions/actionGoodsFind";
+import { actionGoodsPopular } from "../../actions/actionGoodsPopular";
 import { actionOrders } from "../../actions/actionOrders";
-import { actionPromiseClear, store } from "../../reducers";
-import { actionFeedAdd, actionFeedCategoryGoods, actionFeedClear, actionFeedGoodsFind } from "../../reducers/feedReducer";
 import { AdminLayoutPage } from "../admin/AdminLayoutPage";
 import { CCartPage } from "../CartPage";
 import { GoodList } from "../common/GoodList";
 import { CProtectedRoute } from "../common/ProtectedRoute";
 import { CDashboardPage } from "../DashboardPage";
 import { GoodPage } from "../GoodPage";
-import { CGoodsPage, GoodsPage } from "../GoodsPage";
 import { Aside } from "../layout/Aside";
 import Content from "../layout/Content";
 import { Footer } from "../layout/Footer";
 import { Header } from "../layout/Header";
 import { MainPage } from "../MainPage";
+import { CAdminGoodsPageContainer } from "./GoodsPageContainer";
+import { CAdminGoodsSearchPageContainer } from "./GoodsSearchPageContainer";
 
-const GoodsPageContainer = () => {
+const GoodPageContainer = ({ onLoad }) => {
     const params = useParams();
-    const category = useSelector((state) => state.promise?.catById?.payload || null);
-    const goods = useSelector((state) => state.promise?.feedCategoryGoods?.payload || []);
-    const feed = useSelector((state) => state.feed?.payload || []);
-    const dispatch = useDispatch();
-    const [searchParams] = useSearchParams();
-    const orderBy = searchParams.get("orderBy") || "_id";
-
     useEffect(() => {
-        if (params._id) {
-            dispatch(actionCatById({ _id: params._id }));
-        }
+        onLoad({ _id: params._id });
+    }, []);
 
-        return () => {
-            dispatch(actionPromiseClear("catById"));
-        };
-    }, [params._id]);
+    return <GoodPage />;
+};
 
-    useEffect(() => {
-        dispatch(actionFeedClear());
-        dispatch(actionPromiseClear("feedCategoryGoods"));
-        dispatch(actionFeedCategoryGoods({ category, orderBy, skip: 0 }));
-    }, [orderBy, category]);
+const CGoodPageContainer = connect(null, {
+    onLoad: ({ _id }) => actionGoodById({ _id }),
+})(GoodPageContainer);
 
+const DashboardPageContainer = ({ onLoad }) => {
     useEffect(() => {
-        dispatch(actionFeedCategoryGoods({ skip: goods?.length || 0, orderBy }));
-        window.onscroll = (e) => {
-            if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
-                const {
-                    feed,
-                    promise: { feedCategoryGoods },
-                } = store.getState();
-
-                if (feedCategoryGoods.status !== "PENDING") {
-                    dispatch(actionFeedCategoryGoods({ skip: feed.payload?.length || 0, orderBy }));
-                }
-            }
-        };
-        return () => {
-            dispatch(actionFeedClear());
-            dispatch(actionPromiseClear("feedCategoryGoods"));
-            window.onscroll = null;
-        };
+        onLoad();
     }, []);
 
-    useEffect(() => {
-        if (goods?.length) store.dispatch(actionFeedAdd(goods));
-    }, [goods]);
-    return <CGoodsPage goods={feed} />;
+    return <CDashboardPage />;
 };
 
-const GoodsSearchPageContainer = () => {
-    const goods = useSelector((state) => state.promise?.feedGoodsFind?.payload || []);
-    const feed = useSelector((state) => state.feed?.payload || []);
-    const dispatch = useDispatch();
-    const [searchParams] = useSearchParams();
-    const orderBy = searchParams.get("orderBy") || "_id";
-    const text = searchParams.get("text") || "";
+const CDashboardPageContainer = connect(null, {
+    onLoad: () => actionOrders(),
+})(DashboardPageContainer);
 
-    useEffect(() => {
-        dispatch(actionFeedClear());
-        dispatch(actionPromiseClear("feedGoodsFind"));
-        dispatch(actionFeedGoodsFind({ text, orderBy, skip: 0 }));
-    }, [orderBy, text]);
-
-    useEffect(() => {
-        dispatch(actionFeedGoodsFind({ text, skip: goods?.length || 0, orderBy }));
-        window.onscroll = (e) => {
-            if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
-                const {
-                    feed,
-                    promise: { feedGoodsFind },
-                } = store.getState();
+const CGoodsList = connect((state) => ({ goods: state.promise?.pageGoodsFind?.payload || [] }))(GoodList);
 
-                if (feedGoodsFind.status !== "PENDING") {
-                    dispatch(actionFeedGoodsFind({ text, skip: feed.payload?.length || 0, orderBy }));
-                }
-            }
-        };
-        return () => {
-            dispatch(actionFeedClear());
-            dispatch(actionPromiseClear("feedGoodsFind"));
-            window.onscroll = null;
-        };
-    }, []);
+const GoodsListContainer = ({ onLoad }) => {
+    const params = useParams();
 
     useEffect(() => {
-        if (goods?.length) store.dispatch(actionFeedAdd(goods));
-    }, [goods]);
+        onLoad({ text: params.searchData, promiseName: "pageGoodsFind" });
+    }, [params.searchData]);
 
-    return <GoodsPage goods={feed} />;
+    return <CGoodsList />;
 };
 
-const GoodPageContainer = () => {
-    const params = useParams();
-    const dispatch = useDispatch();
-    useEffect(() => {
-        dispatch(actionGoodById({ _id: params._id }));
-    }, []);
-
-    return <GoodPage />;
-};
+const CGoodsListContainer = connect(null, {
+    onLoad: ({ text, promiseName }) => actionOrders({ text, promiseName }),
+})(GoodsListContainer);
 
-const DashboardPageContainer = () => {
-    const dispatch = useDispatch();
+const MainPageContainer = ({ onLoad, goods }) => {
     useEffect(() => {
-        dispatch(actionOrders());
+        onLoad();
     }, []);
 
-    return <CDashboardPage />;
+    return <MainPage goods={goods || []} />;
 };
 
-const CGoodsList = connect((state) => ({ goods: state.promise?.pageGoodsFind?.payload || [] }))(GoodList);
-
-const GoodsListContainer = () => {
-    const params = useParams();
-    const dispatch = useDispatch();
-    useEffect(() => {
-        dispatch(actionGoodsFind({ text: params.searchData, promiseName: "pageGoodsFind" }));
-    }, [params.searchData]);
-
-    return <CGoodsList />;
-};
+const CMainPageContainer = connect((state) => ({ goods: state.promise?.goodsPopular?.payload || [] }), {
+    onLoad: () => actionGoodsPopular(),
+})(MainPageContainer);
 
 export const LayoutPage = () => {
     const location = useLocation();
@@ -160,7 +86,7 @@ export const LayoutPage = () => {
                 <Grid xs={location.pathname.match(/(\/categor)|(\/good)|(\/order)|(\/admin)+/) ? 11 : 14} item>
                     <Content>
                         <Routes>
-                            <Route path="/" exact element={<MainPage />} />
+                            <Route path="/" exact element={<CMainPageContainer />} />
                             <Route
                                 path="/cart"
                                 exact
@@ -170,11 +96,10 @@ export const LayoutPage = () => {
                                     </CProtectedRoute>
                                 }
                             />
-                            <Route path="/search/:searchData/" element={<GoodsListContainer />} exact />
-                            <Route path="/category/:_id" element={<GoodsPageContainer />} />
-                            <Route path="/category/" element={<GoodsPageContainer />} />
-                            <Route path="/good/:_id" element={<GoodPageContainer />} />
-                            <Route path="/goods/search" element={<GoodsSearchPageContainer />} />
+                            {/* <Route path="/search/:searchData/" element={<CGoodsListContainer />} exact /> */}
+                            <Route path="/category/:_id" element={<CAdminGoodsPageContainer />} />
+                            <Route path="/good/:_id" element={<CGoodPageContainer />} />
+                            <Route path="/goods/search" element={<CAdminGoodsSearchPageContainer />} />
                             <Route
                                 path="/admin/*"
                                 exact
@@ -189,7 +114,7 @@ export const LayoutPage = () => {
                                 exact
                                 element={
                                     <CProtectedRoute roles={["active"]} fallback="/">
-                                        <DashboardPageContainer />
+                                        <CDashboardPageContainer />
                                     </CProtectedRoute>
                                 }
                             />

+ 2 - 5
src/components/MainPage/index.js

@@ -1,11 +1,8 @@
 import { Box, Stack, Typography } from "@mui/material";
-import { useSelector } from "react-redux";
 import MainPageImage from "../../images/main-page-image.png";
 import { GoodCardSlider } from "../common/GoodCardSlider";
 
-const MainPage = () => {
-    const popularGoods = useSelector((state) => state.promise?.goodsPopular?.payload || []);
-
+const MainPage = ({ goods = [] } = {}) => {
     return (
         <Box className="MainPage">
             <Stack spacing={3}>
@@ -16,7 +13,7 @@ const MainPage = () => {
                     </Typography>
                 </Box>
                 <Box>
-                    <GoodCardSlider goods={popularGoods} />
+                    <GoodCardSlider goods={goods} />
                 </Box>
             </Stack>
         </Box>

+ 1 - 1
src/components/common/InfScroll/index.js

@@ -7,7 +7,7 @@ export const InfScroll = ({ component = null, onScroll = null, items = [], promi
     const dispatch = useDispatch();
     useEffect(() => {
         window.onscroll = (e) => {
-            if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 200) {
+            if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 400) {
                 if (promiseStatus !== "PENDING") {
                     onScroll && onScroll();
                 }