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;