cari

Rumah  >  Soal Jawab  >  teks badan

Pelanggaran invarian tidak tertangkap: Diberikan dengan lebih banyak cangkuk berbanding pemaparan sebelumnya

Saya mempunyai komponen yang kelihatan seperti ini (versi yang sangat mudah):

const component = (props: PropTypes) => {

    const [allResultsVisible, setAllResultsVisible] = useState(false);

    const renderResults = () => {
        return (
            <section>
                <p onClick={ setAllResultsVisible(!allResultsVisible) }>
                    More results v
                </p>
                {
                    allResultsVisible &&
                        <section className="entity-block--hidden-results">
                            ...
                        </section>
                }
            </section>
        );
    };

    return <div>{ renderResults() }</div>;
}

Apabila saya memuatkan halaman yang menggunakan komponen ini, saya mendapat ralat ini: Uncaught Invariant Violation: Rendered more hooks than during the previous render. Saya cuba mencari penjelasan untuk ralat ini, tetapi carian saya tiada hasil.

Apabila saya mengubah suai sedikit komponen:

const component = (props: PropTypes) => {

    const [allResultsVisible, setAllResultsVisible] = useState(false);

    const handleToggle = () => {
        setAllResultsVisible(!allResultsVisible);
    }

    const renderResults = () => {
        return (
            <section>
                <p onClick={ handleToggle }>
                    More results v
                </p>
                {
                    allResultsVisible &&
                        <section className="entity-block--hidden-results">
                            ...
                        </section>
                }
            </section>
        );
    };

    return <div>{ renderResults() }</div>;
}

Saya tidak lagi mendapat ralat itu. Adakah kerana saya dalam fungsi renderResults 返回的 jsx 中包含了 setState? Alangkah baiknya jika terdapat penjelasan mengapa pembetulan ini berfungsi.

P粉477369269P粉477369269277 hari yang lalu604

membalas semua(2)saya akan balas

  • P粉729198207

    P粉7291982072024-03-26 10:59:40

    Saya juga mengalami masalah yang sama. Apa yang saya lakukan ialah ini:

    const Table = (listings) => {
    
        const {isLoading} = useSelector(state => state.tableReducer);
    
        if(isLoading){
            return <h1>Loading...</h1>
        }
    
        useEffect(() => {
           console.log("Run something")
        }, [])
    
        return (<table>{listings}</table>)
    }

    Saya rasa apa yang berlaku ialah pada paparan pertama, komponen kembali awal dan useEffect tidak berjalan. Apabila keadaan isLoading berubah dan useEffect berjalan, saya mendapat ralat - Cangkuk membuat lebih banyak kali daripada sebelumnya.

    Perubahan mudah menyelesaikan masalah:

    const Table = (listings) => {
        
        const {isLoading} = useSelector(state => state.tableReducer);
            
        useEffect(() => {
            console.log("Run something")
        }, [])
        
        if(isLoading){
            return <h1>Loading...</h1>
        }
        return (<table>{listings}</table>)
    }

    balas
    0
  • P粉448346289

    P粉4483462892024-03-26 10:39:49

    Pembetulan berfungsi kerana contoh kod pertama (kod yang menyinggung) memanggil onClick 内的函数,而第二个代码示例(有效的代码示例)则将函数传递给了 onClick. Perbezaannya ialah kurungan yang sangat penting, yang dalam JavaScript bermaksud "panggil kod ini".

    Fikirkan seperti ini: dalam contoh kod pertama, anda membuat component 时,都会调用 renderResults。每次发生这种情况时,都会调用 setAllResultsVisible(!allResultsVisible) setiap kali dan bukannya menunggu klik. Memandangkan React melakukan pemaparan mengikut jadualnya sendiri, tiada cara untuk menentukan berapa kali ini akan berlaku.

    Dari dokumentasi React:

    React mengendalikan dokumen acara

    Nota: Saya tidak boleh mendapatkan mesej ralat yang tepat semasa menjalankan contoh kod pertama dalam kotak pasir. Ralat saya melibatkan gelung tak terhingga. Mungkin versi React yang lebih baru menghasilkan ralat yang diterangkan?

    balas
    0
  • Batalbalas