P粉8074716042023-09-05 09:01:34
问题出在 Cards
组件中,它直接在组件的函数体中将 Axios GET 请求作为无意的副作用。这很可能会创建一个渲染循环,或者至少在每次 Cards
渲染时发出 GET 请求。
将此代码移至 useEffect
挂钩中,以便在组件安装后调用它。
示例:
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);
您使用的是相当旧的 Redux 代码,我们通常不再使用 connect
高阶组件,因为 useDispatch
和 useSelector
挂钩取代了它的用法。目前的标准是使用 Redux-Toolkit
,确实减少了您需要编写的样板文件的数量。
以下是更新建议示例:
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 代码、操作类型、操作创建者...全部由单个状态切片替换。
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;