【问题标题】:Uncaught Error: Too many re-renders in react未捕获的错误:反应中的重新渲染过多
【发布时间】:2020-08-20 11:25:21
【问题描述】:

这是我的代码。主页.js 我使用 react-redux 钩子 useSelector 和 useDispatch 来使用状态和调度请求。

import React from 'react'
import StyledBanner from '../../components/StyledBanner';
import FeaturedRoom from './FeaturedRoom';
import Hero from '../../components/Hero'
import {useDispatch, useSelector} from 'react-redux'
import {fetchRooms, fetchFeatured} from '../../redux'


function Home() {
    const dispatch = useDispatch()
    dispatch(fetchRooms())
    dispatch(fetchFeatured())
    const featuredRooms = useSelector(state=>state.roomReducer.featuredRooms)
    return (
        <div className="container-fluid p-0">
            <Hero>
                <StyledBanner title="best rooms" subtitle="subtitle">
                    <div className="subtitle">
                    </div>
                    <button className="btn btn-warning">Rooms</button>
                </StyledBanner>   
            </Hero>
            <FeaturedRoom featuredRooms={featuredRooms}/>
        </div>
    )
}

export default Home

这是 FeaturedRoom.js

import React from 'react'
import StyledTitle from '../../components/StyledTitle';
import StyledButton from '../../components/StyledButton'
import {Link} from 'react-router-dom'

export function FeaturedRoom({featuredRooms}) {
    return (
        <div className="mt-3  mb-3 featured-container">
            <div className="featured-wrapper">
                <StyledTitle title="featured rooms"/>
                <div className="featured-rooms">

                    {
                        featuredRooms.map(room=>(
                            <div key={room.id} className="featured-item">
                                <div className="price-tag">
                                    <span>Rs {room.price}</span>
                                    <span>per night</span>
                                </div>
                                <img src={room.images[0]} className="img-fluid" alt="featured-img"/>
                                <Link to="/"><button>Room</button></Link>
                                <div className="room-name">
                                    {room.name}
                                </div>
                            </div>
                        ))
                    }


                </div>
            </div>
        </div>
    )

}

export default FeaturedRoom

在 FeaturedRoom.js 文件的第二部分,有“链接”。在我单击按钮之前,一切正常。减速机也工作正常。所有的减速器都完美地设置了状态,但是当我点击按钮时,它说

Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
    at renderWithHooks (react-dom.development.js:14815)

【问题讨论】:

    标签: reactjs infinite-loop infinite rerender


    【解决方案1】:

    您的问题在于调度分配之后的 Home 组件。您正在使用组件定义中的两个操作调用调度。如果您希望在挂载时触发这些操作,请将它们放入 useEffect 挂钩中。

    import React, { useEffect } from 'react'
    import StyledBanner from '../../components/StyledBanner';
    import FeaturedRoom from './FeaturedRoom';
    import Hero from '../../components/Hero'
    import {useDispatch, useSelector} from 'react-redux'
    import {fetchRooms, fetchFeatured} from '../../redux'
    
    
    function Home() {
        const dispatch = useDispatch();
        const featuredRooms = useSelector(state=>state.roomReducer.featuredRooms)
    
        useEffect(() => {
            dispatch(fetchRooms())
            dispatch(fetchFeatured())
        }, [dispatch])
    
        return (
            <div className="container-fluid p-0">
                <Hero>
                    <StyledBanner title="best rooms" subtitle="subtitle">
                        <div className="subtitle">
                        </div>
                        <button className="btn btn-warning">Rooms</button>
                    </StyledBanner>   
                </Hero>
                <FeaturedRoom featuredRooms={featuredRooms}/>
            </div>
        )
    }
    
    export default Home
    

    在这种情况下,我们使用useEffect 的方式与旧的componentDidMount 类似。该钩子的官方文档是here

    我也想到(给定您的函数名称)您正在尝试调用一个 repo 以检索特色房间,将结果加载到商店中,然后从商店中选择它,然后提供给 @987654326 @ 零件。如果是这种情况,我建议将 Home 包装在一个组件中,该组件在安装时进行调用,并加载 redux 存储。然后子组件可以使用useSelctor 钩子,结合useEffect 钩子(以观察存储的featuredRooms 部分的变化)将结果提供给FeaturedRoom。我希望这有点清楚。

    编辑:

    好的,让我们试试这个,看看它对你有什么作用。在需要该数据的组件内移动选择器。像这样的:

    import React, { useEffect } from 'react'
    import StyledBanner from '../../components/StyledBanner';
    import FeaturedRoom from './FeaturedRoom';
    import Hero from '../../components/Hero'
    import {useDispatch, useSelector} from 'react-redux'
    import {fetchRooms, fetchFeatured} from '../../redux'
    
    
    function Home() {
        const dispatch = useDispatch();
    
        useEffect(() => {
            dispatch(fetchRooms())
            dispatch(fetchFeatured())
        }, [dispatch])
    
    
        return (
            <div className="container-fluid p-0">
                <Hero>
                    <StyledBanner title="best rooms" subtitle="subtitle">
                        <div className="subtitle">
                        </div>
                        <button className="btn btn-warning">Rooms</button>
                    </StyledBanner>   
                </Hero>
                <FeaturedRoom />
            </div>
        )
    }
    
    export default Home
    
    
    function FeaturedRoom() {
        const featuredRooms = useSelector(state=>state.roomReducer.featuredRooms);
    
        /*  .... the rest of your component ... */
    }
    

    如果您需要观察featuredRooms 属性的变化,可以将该逻辑放在FeaturedRoom 组件内的另一个useEffect 中。

    【讨论】:

    • 谢谢。有效。我包装了 home 组件等等......
    • 当我使用你上面建议的 useEffet 时,它抛出了以下错误。警告:已超出最大更新深度。当组件在 useEffect 中调用 setState 时,可能会发生这种情况,但 useEffect 要么没有依赖数组,要么每次渲染时依赖项之一发生变化。最终,我在 index.js 中按如下方式包装了组件并工作 ReactDOM.render( document.getElementById( 'root') );` RoomProvider 加载存储的地方。
    猜你喜欢
    • 2020-12-30
    • 2022-11-30
    • 1970-01-01
    • 2020-09-29
    • 2023-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-31
    相关资源
    最近更新 更多