Pelanggaran invarian tidak tertangkap: Diberikan dengan lebih banyak cangkuk berbanding pemaparan sebelumnya
P粉477369269
P粉477369269 2024-03-25 16:50:53
0
2
606

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粉477369269
P粉477369269

membalas semua(2)
P粉729198207

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>)
}
P粉448346289

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?

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