Rumah  >  Soal Jawab  >  teks badan

React reports props."function" bukan fungsi

<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粉475315142P粉475315142382 hari yang lalu596

membalas semua(1)saya akan balas

  • P粉807471604

    P粉8074716042023-09-05 09:01:34

    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;
    

    balas
    0
  • Batalbalas