Heim  >  Fragen und Antworten  >  Hauptteil

React Reports Requisiten. „Funktion“ ist keine Funktion

<p>Ich erstelle meinen ersten Online-Shop und stoße auf ein Problem. Ich habe eine gefälschte API erstellt, die Produktkartendaten enthält, und wenn ich sie mit <code>axios.get</code> erhalte und zum Status hinzufüge, erhalte ich die Meldung „props.addCardData ist keine Funktion“.Ich muss sagen, alles funktioniert gut, bis ich <code>axios.get</code> hinzufüge. Andere Funktionen verwende ich auf die gleiche Weise wie die Funktion <code>addCardData</code>: Ich meine, ich habe <code>mapDispatchToProps</code> verwendet und ich habe <code>props.addCardData</code> verwendet Ich verwende sie nicht in <code>axios.get</code> Ich hatte vorher keine Probleme damit, die Funktionen zu nutzen. </p> <p>Ich habe vor, die Daten über <code>axios.get</code> abzurufen und eine Funktion aus dem Kartencontainer aufzurufen, die den Versand mit dem Aktionsersteller als Parameter aufruft. </p> <p>Ich habe auch gefunden: „Eigenschaft von undefiniert kann nicht gelesen werden (read ‚addCardData‘).</p> <p>Unten habe ich den Teil des Codes angegeben, der von dem Problem betroffen ist (ich habe angegeben, welcher Code für welche Elemente gilt)</p> <p>Dies ist der Code in der Kartenkomponente (ich habe die Importe hier nicht hinzugefügt, aber natürlich habe ich alle Importe): </p> <pre class="brush:php;toolbar:false;">const Cards = (props) => axios.get('https://mocki.io/v1/8cb0f160-92f7-4cf8-a6c1-f63690df514e') .then(response => { props.addCardData(response.data) }) let CardsArray = Object.keys(props.cardsData).map(card => ( <OfferCard key={card.id} bg={props.cardsData[card].bg} id={props.cardsData[card].tagId} title={props.cardsData[card].title} text={props.cardsData[card].text} button={ <Behälterflüssigkeit> <Row className={'row-cols-auto'}> {props.cardsData[card].button.map(button => ( <CardsButton key={button.id} link={button.link} type={button.type} class={button.class} name={button.name} /> ))} </Zeile> </Container> } /> )) zurückkehren ( <Behälterflüssigkeit> <img src={'./backgrounds/bestoffers.png'} alt={'BEST OFFERS'} className={'img-fluid imgTab'} /> <Row xs={1} md={2} id={'cards-row'} className={'border border-4 g-3'}> {/*row-cols-* – Legen Sie die Kartenbreite fest, indem Sie die Anzahl der Karten in der Zeile festlegen*/} {cardsArray} </Zeile> </Container> ) } Standardkarten exportieren</pre> <p>Dies ist der Code in <code>CardsContainer</code>: </p> <pre class="lang-js Prettyprint-override"><code>const mapStateToProps = (state) => zurückkehren { CardsData: state.homePage.cardsData } } const mapDispatchToProps = (dispatch) => zurückkehren { addCardData: (data) => Versand(addCardsData(data)) } } } const CardsContainer = connect(mapStateToProps, mapDispatchToProps)(Cards); Standard-CardsContainer exportieren </code></pre> <p>Dies ist der Code im Reduzierer: </p> <pre class="lang-js Prettyprint-override"><code>... homePageCardsData = 'HOMEPAGE-CARDS-DATA' initialState = {...} – enthält "cardsData: {}" const homePageReducer = (state = initialState, action) => let stateCopy; switch (action.type) { case homePageCardsData: { stateCopy = {...state, CardsData: action.data} brechen } ... Standard: Rückgabestatus; } return stateCopy; ...... - einige Funktionen hier (nicht unbedingt bekannt) }export const addCardsData = (data) => Typ: homePageCardsData, Daten: Daten }) </code></pre> <p>Wenn ich etwas versuche wie: </p> <pre class="lang-js Prettyprint-override"><code>const addCard = props.addCardData axios.get('https://mocki.io/v1/8cb0f160-92f7-4cf8-a6c1-f63690df514e') .then(response => { addCard(response.data) }) </code></pre> <p>Ich bekomme eine Verzögerung auf localhost (auf der Homepage!!), alles beginnt langsam zu rendern und in 70 % der Fälle wird der Kartenblock nicht gerendert. In anderen Fällen kann es nach einiger Zeit zu einem Rendern kommen (seltener Fall). Auf der AdminPanel-Seite rendere ich <code>Cards</code>, weil ich die Änderungen beim Testen des Menüs sehen muss. Ich erhalte die Meldung „TypeError: addCard ist keine Funktion </p>“. <p>Wenn ich diesen Code aus der Komponente entferne, funktioniert alles einwandfrei. </p> <p>Ich muss auch sagen, dass ich den „Debugger“ verwendet und ihn in <code>homePageCardsData</code> platziert habe. Das Skript stoppt im Debugger (nach <code>StateCopy</code> und vor <code>break</code>). Das bedeutet, dass das Skript korrekt ist, <code>dispatch</code> funktioniert und ich in den Fall <code>homePageCardsData</code> gelangen kann. </p>
P粉475315142P粉475315142382 Tage vor597

Antworte allen(1)Ich werde antworten

  • P粉807471604

    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 高阶组件,因为 useDispatchuseSelector 挂钩取代了它的用法。目前的标准是使用 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;
    

    Antwort
    0
  • StornierenAntwort