反应无限渲染循环

时间:2021-01-08 10:42:00

标签: javascript reactjs redux infinite-loop

我创建了一个组件,它需要在应用程序的多个部分单独显示 -(在我的导航内、主页上和单独的路由上)。因此,我在此组件的 useEffect 中进行了所有操作调度(用于读取数据的 api 调用):

useEffect(() => {
    dispatch(time.read())
    dispatch(pause.read())
    dispatch(travel.read())
    dispatch(distances.read())
}, [])

如你所见,这个效果应该只运行一次(当组件挂载时)。

我没有在这个组件内部或外部调度这些特定的操作。

此组件在 3 个位置呈现(导航内部、其自己的 /time 路径中和 home 组件内部)。我可以在导航内部和 /time 上同时渲染它,没有问题。它按其应有的方式运行(当我从导航中进行更改时,它们会在 /time 上进行镜像,因为它们都与 redux 捆绑在一起)。最后是 Home 组件。

当我第一次尝试在 Home 组件上渲染时,加载需要一段时间,然后我尝试通过我的 v4 地址(同一网络)从我的移动设备打开它,加载时间太长。在这一点上,我的笔记本电脑开始听起来像直升机,所以我打开了 htop,内存使用率和 CPU 使用率几乎达到了最大值,我打开了我的服务器日志,每秒看到数百个请求。以下是我在 Home 组件中呈现此组件的方式:

import React from "react"
import { useSelector } from "react-redux"
import { NavLink } from "react-router-dom"
import "./Home.css"

import {
    FaCarCrash,
    CgProfile,
    AiOutlineShop,
    TiVideo,
} from 'react-icons/all'
import Tracking from "../TimeTracking/Tracking" /*This is the component which causes all the toruble*/

export default function Home(props) {

    const current = useSelector(state => state.user.currentUser)

    return (
        <div className="Home container">
            <div id="links">
                <NavLink to="/create_job/">
                    <FaCarCrash />
                    <p> CREATE JOB </p>
                </NavLink>
                <NavLink to={"/profile/" + current._id}>
                    <CgProfile />
                    <p> PROFILE </p>
                </NavLink>
                <NavLink to="/shop/view/">
                    <AiOutlineShop />
                    <p> SHOP </p>
                </NavLink>
                <NavLink to="/tutorials/">
                    <TiVideo />
                    <p> TRAINING </p>
                </NavLink>
            </div>
            <Tracking /> /*This is the component which causes all the toruble*/
        </div>
    )
}

如您所见,没有什么特别之处 - 一个简单的功能组件,甚至不分派任何操作。这里只和 redux 通信的是 useSelector。

这里是我渲染 Home 组件的地方:

import React, { Fragment } from 'react'
import { Route } from 'react-router-dom'

/*...other imports...*/
import Home from "../components/Mobile/Home"
/*...other imports...*/

export default props => (
    <Fragment>
        /*...other routes...*/
        <Route path="/home" component={Home} />
        /*...other routes...*/
    </Fragment> /* just a fragment wrapper around the routes for the user. This component is later rendered inside of my <Router> </Router>. This is done because the app has a lot of different routes. */
)

出于某种原因,即使我不与应用程序交互,该组件也会一遍又一遍地重新渲染。我已经检查过我是否曾经从 2 个可能导致此问题的地方发送相同的操作,但我没有。我知道我没有提供太多内容,但在这个问题中确实没有太多可展示的内容,我只是希望有人以前遇到过。我以前处理过无限渲染循环,它们通常很明显并且很容易解决,但这个有点奇怪。

1 个答案:

答案 0 :(得分:0)

我已经解决了我的问题。我实际上使用的是旧版本的 RootRouter.js,其中 Home 组件声明如下:

<Route path="/home" component={<Home user={this.props.user} />} />

而且我渲染的 Home 组件也是一个旧版本(它是一个类组件,而不是我在问题中写的函数组件)。

所以这里是导致问题的原因:

user prop 是在声明 Home 路由时向下传递的,它持有 state.user 的值

然后在 Home 组件中,我使用 mapStateToProps 并将 user 映射到 props,并将其设置为 state.user.currentUser

这会导致 user prop 在渲染组件时声明一次,然后在组件渲染后更改,然后在下一次渲染时再次更改,依此类推。 react 没有响应渲染循环的原因是因为 user 属性为每个渲染保存了不同的值。