如何修复反应过多的重新渲染错误?

Posted

技术标签:

【中文标题】如何修复反应过多的重新渲染错误?【英文标题】:How to fix react too many re-renders error? 【发布时间】:2020-12-30 20:34:05 【问题描述】:

我正在尝试从子组件内部触发模式,但出现以下错误。

Too many re-renders error

我的父子组件代码如下:

Onboard.jsx

import React from 'react'
import  Row  from 'react-bootstrap'

import  PersonalDetails  from './personalDetails'
import  EmailVerification  from './emailVerification'
import  Form  from './form'
import  FAQs  from './faq'
import  LeftCol, RightCol  from './styles'
import  Modal, Button  from 'react-bootstrap'

const OnboardPage = props => 
    const [show, setShow] = React.useState(false);
    const handleShow = (showValue) => setShow(showValue);

    return (
        <Row>
            <LeftCol md=8>
                <PersonalDetails parentShowFn=handleShow/>
                <Form />
            </LeftCol>
            <RightCol md=4>
                <EmailVerification />
                <FAQs />
            </RightCol>
            <Modal show=show onHide=handleShow(false)>
                <Modal.Header closeButton>
                  <Modal.Title>Modal heading</Modal.Title>
                </Modal.Header>
                <Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
                <Modal.Footer>
                  <Button variant="secondary" onClick=handleShow(false)>
                    Close
                  </Button>
                  <Button variant="primary" onClick=handleShow(false)>
                    Save Changes
                  </Button>
                </Modal.Footer>
            </Modal>
        </Row>
    )


export default OnboardPage

Personaldetails.jsx

import React from 'react'

import  colors  from '../../../../res'
import  TitleText, CommonText, SubHeadingText  from '../../../commons/freelancer/texts'
import  Container, TitleRow, DetailsRow, DetailsItem, EditBtn  from './personalDetailsStyles'
import  Modal, Button  from 'react-bootstrap'
// import EditDetailsModal from './EditDetailsModal'

const PersonalDetails = (parentShowFn) => 

    return (

        <Container>
        <TitleRow>
            <TitleText>Personal Details</TitleText>
            <EditBtn onClick=() => parentShowFn(true)>Edit</EditBtn>
        </TitleRow>
        </Container>
    )


    

export default PersonalDetails

我认为这可能是因为某些渲染函数被无限调用,但我似乎无法修复错误。

【问题讨论】:

这能回答你的问题吗? Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop 您的按钮点击处理程序错误。他们在每次渲染时调用您的 handleShow 函数,这会触发无限次重新渲染。你甚至不需要handleShow。将您的点击处理程序更改为 () =&gt; setShow(true) 或 false。 【参考方案1】:

您为setShow 设置了错误的回调。每次重新渲染时都调用 setShow 。 -> 无限循环

应该像这样传递回调:() =&gt; setShow(flase);

【讨论】:

【参考方案2】:

问题出在Onboard.js,像()=&gt;handleShow(false)handleShow这样在React组件中传递函数,因为函数没有绑定特定事件,每次渲染时都会被调用,应该是这样的

import React from 'react'
import  Row  from 'react-bootstrap'

import  PersonalDetails  from './personalDetails'
import  EmailVerification  from './emailVerification'
import  Form  from './form'
import  FAQs  from './faq'
import  LeftCol, RightCol  from './styles'
import  Modal, Button  from 'react-bootstrap'

const OnboardPage = props => 
    const [show, setShow] = React.useState(false);
    const handleShow = (showValue) => setShow(showValue);

    return (
        <Row>
            <LeftCol md=8>
                <PersonalDetails parentShowFn=handleShow/>
                <Form />
            </LeftCol>
            <RightCol md=4>
                <EmailVerification />
                <FAQs />
            </RightCol>
            <Modal show=show onHide=()=>handleShow(false)>
/* It was getting called again and again and throwing limit error*/
                <Modal.Header closeButton>
                  <Modal.Title>Modal heading</Modal.Title>
                </Modal.Header>
                <Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
                <Modal.Footer>
                  <Button variant="secondary" onClick=()=>handleShow(false)>
                    Close
                  </Button>
                  <Button variant="primary" onClick=()=>handleShow(false)>
                    Save Changes
                  </Button>
                </Modal.Footer>
            </Modal>
        </Row>
    )


export default OnboardPage

【讨论】:

以上是关于如何修复反应过多的重新渲染错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复“TypeError:fsevents 不是构造函数”反应错误

在反应中更改状态时组件不会重新渲染

在回调函数中使用 setState 挂钩时反应过多的重新渲染

如何使用钩子在反应 i18next 中修复“未指定回退 UI”

redux计算数据重新渲染如何修复

“错误:重新渲染过多。React 限制了渲染次数以防止无限循环。”