React reports props."function" bukan fungsi
P粉475315142
P粉475315142 2023-09-04 10:38:59
0
1
657
<p>Saya sedang mencipta kedai dalam talian pertama saya dan saya menghadapi masalah. Saya membuat API palsu yang mengandungi data kad produk dan apabila saya mendapatkannya menggunakan <code>axios.get</code> dan menambah kepada keadaan saya mendapat "props.addCardData is not a function".Saya mesti katakan, semuanya berfungsi dengan baik sehingga saya menambah <code>axios.get</code> Fungsi lain saya menggunakan cara yang sama seperti fungsi <code>addCardData</code>: Maksud saya, saya menggunakan <code>mapDispatchToProps</code> dan saya menggunakan <code>props.addCardData</code> Saya tidak menggunakannya dalam <code>axios.get</code> Saya tidak mempunyai masalah menggunakan mana-mana ciri sebelum ini. </p> <p>Saya merancang untuk mendapatkan data melalui <code>axios.get</code> dan memanggil fungsi daripada bekas kad yang akan memanggil penghantaran dengan pencipta tindakan sebagai parameter. </p> <p>Saya juga mendapati "Tidak boleh membaca sifat yang tidak ditentukan (baca 'addCardData').</p> <p>Di bawah, saya telah menunjukkan bahagian kod yang terjejas oleh isu (saya telah menyatakan kod yang digunakan untuk elemen yang mana)</p> <p>Ini ialah kod dalam komponen Kad (saya tidak menambah import di sini, tetapi ofc saya mempunyai semua import): </p> <pre class="brush:php;toolbar:false;">const Kad = (props) => axios.get('https://mocki.io/v1/8cb0f160-92f7-4cf8-a6c1-f63690df514e') .then(respon => { props.addCardData(response.data) }) biarkan cardsArray = Object.keys(props.cardsData).map(card => ( <Kad Tawaran key={card.id} bg={props.cardsData[card].bg} id={props.cardsData[card].tagId} title={props.cardsData[card].title} text={props.cardsData[card].text} butang={ <Bendalir bekas> <Nama kelas baris={'row-cols-auto'}> {props.cardsData[card].button.map(button => ( <Button Kad key={button.id} pautan={button.link} type={button.type} class={button.class} name={button.name} /> ))} </Row> </Bekas> } /> )) kembali ( <Bendalir bekas> <img src={'./backgrounds/bestoffers.png'} alt={'TAWARAN TERBAIK'} className={'img-fluid imgTab'} /> <Baris xs={1} md={2} id={'cards-row'} className={'sempadan sempadan-4 g-3'}> {/*row-cols-* - tetapkan lebar kad dengan menetapkan jumlah kad dalam baris*/} {cardsArray} </Row> </Bekas> ) } eksport Kad lalai</pra> <p>Ini ialah kod dalam <kod>CardsContainer</code>: </p> <pre class="lang-js prettyprint-override"><code>const mapStateToProps = (negeri) => kembali { cardsData: state.homePage.cardsData } } const mapDispatchToProps = (dispatch) => kembali { addCardData: (data) => penghantaran(addCardsData(data)) } } } const CardsContainer = connect(mapStateToProps, mapDispatchToProps)(Kad); eksport CardsContainer lalai </code></pre> <p>Ini ialah kod dalam pengecil: </p> <pre class="lang-js prettyprint-override"><code>... homePageCardsData = 'HOMEPAGE-CARDS-DATA' initialState = {...} - termasuk "cardsData: {}" const homePageReducer = (state = initialState, action) => biarkan stateCopy; suis (action.type) { case homePageCardsData: { stateCopy = {...state, cardsData: action.data} rehat } ... lalai: keadaan kembali; } kembalikan stateCopy; ...... - beberapa fungsi di sini (tidak perlu diketahui) }eksport const addCardsData = (data) => jenis: homePageCardsData, data: data }) </code></pre> <p>Apabila saya mencuba sesuatu seperti: </p> <pre class="lang-js prettyprint-override"><code>const addCard = props.addCardData axios.get('https://mocki.io/v1/8cb0f160-92f7-4cf8-a6c1-f63690df514e') .then(respon => { addCard(response.data) }) </code></pre> <p>Saya semakin ketinggalan pada localhost (di halaman utama!!), semuanya mula dipaparkan dengan perlahan dan 70% daripada masa, blok kad tidak dipaparkan. Dalam kes lain ia boleh menyebabkan selepas beberapa ketika (peluang yang jarang berlaku). Pada halaman AdminPanel, saya memaparkan <code>Kad</code> kerana saya perlu melihat perubahan semasa menguji menu, saya mendapat "TypeError: addCard is not a function." <p>Jika saya mengalih keluar kod ini daripada komponen - semuanya berfungsi dengan baik. </p> <p>Saya juga mesti mengatakan bahawa saya menggunakan "debugger" dan meletakkannya dalam <kod>homePageCardsData</code>. Skrip berhenti pada penyahpepijat (selepas <code>StateCopy</code> dan sebelum <code>break</code>). Ini bermakna skrip adalah betul, <code>dispatch</code> berfungsi dan saya boleh masuk ke dalam kes <code>homePageCardsData</code>. </p>
P粉475315142
P粉475315142

membalas semua(1)
P粉807471604

Masalahnya ialah Cards 组件中,它直接在组件的函数体中将 Axios GET 请求作为无意的副作用。这很可能会创建一个渲染循环,或者至少在每次 Cards membuat permintaan GET semasa membuat rendering.

Alihkan kod ini ke dalam cangkuk useEffect supaya ia akan dipanggil selepas komponen dipasang.

Contoh:

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);

Anda menggunakan kod Redux lama yang biasanya kami tidak gunakan lagi connect 高阶组件,因为 useDispatchuseSelector 挂钩取代了它的用法。目前的标准是使用 Redux-Toolkit, yang mengurangkan jumlah boilerplate yang anda perlukan untuk menulis.

Berikut adalah contoh cadangan kemas kini:

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 (
    ...
  );
};

kod pengurang, jenis operasi, pencipta operasi... semuanya digantikan dengan kepingan keadaan tunggal.

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;

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan