P粉8074716042023-09-05 09:01:34
The problem is in the Cards
component, which makes an Axios GET request as an unintentional side effect directly in the component's function body. This will most likely create a render loop, or at least make a GET request every time Cards
is rendered.
Move this code into the useEffect
hook so that it is called after the component is installed.
Example:
const Cards = ({ addCardsData, cardsData }) => { useEffect(() => { axios .get("https://mocki.io/v1/8cb0f160-92f7-4cf8-a6c1-f63690df514e") .then((response) => { addCardsData(response.data); }); }, [addCardsData]); let cardsArray = Object.keys(cardsData).map((card) => ( <OfferCard key={card.id} bg={cardsData[card].bg} id={cardsData[card].tagId} title={cardsData[card].title} text={cardsData[card].text} button={ <Container fluid> <Row className={"row-cols-auto"}> {cardsData[card].button.map((button) => ( <CardsButton key={button.id} link={button.link} type={button.type} class={button.class} name={button.name} /> ))} </Row> </Container> } /> )); return ( ... ); }; const mapStateToProps = (state) => ({ cardsData: state.homePage.cardsData }); const mapDispatchToProps = { addCardsData }; const CardsContainer = connect(mapStateToProps, mapDispatchToProps)(Cards);
You are using fairly old Redux code and we generally no longer use the connect
higher-order component since the useDispatch
and useSelector
hooks replaced it usage. The current standard is to use the Redux-Toolkit
, which does reduce the amount of boilerplate you need to write.
The following are examples of update suggestions:
import { useDispatch, useSelector } from "react-redux"; ... const Cards = () => { const dispatch = useDispatch(); const cardsData = useSelector(state => state.homePage.cardsData); useEffect(() => { axios .get("https://mocki.io/v1/8cb0f160-92f7-4cf8-a6c1-f63690df514e") .then((response) => { dispatch(addCardsData(response.data)); }); }, [dispatch]); let cardsArray = Object.keys(cardsData).map((card) => ( <OfferCard key={card.id} bg={cardsData[card].bg} id={cardsData[card].tagId} title={cardsData[card].title} text={cardsData[card].text} button={ <Container fluid> <Row className={"row-cols-auto"}> {cardsData[card].button.map((button) => ( <CardsButton key={button.id} link={button.link} type={button.type} class={button.class} name={button.name} /> ))} </Row> </Container> } /> )); return ( ... ); };
reducer code, operation type, operation creator... all replaced by a single state slice.
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
cardsData: {},
... other home page state ...
};
const homePageSlice = createSlice({
name: "homePage",
initialState,
reducers: {
addCardsData: (state, action) => {
state.cardsData = action.payload;
},
... other reducer cases ...
}
});
export const {
addCardsData,
... other generated actions ...
} = homePageSlice.actions;
export default homePageSlice.reducer;