React Reports Requisiten. „Funktion' ist keine Funktion
P粉475315142
P粉475315142 2023-09-04 10:38:59
0
1
640
<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粉475315142
P粉475315142

Antworte allen(1)
P粉807471604

问题出在 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;

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage