首页 > 解决方案 > “错误:重新渲染过多。React 限制渲染次数以防止无限循环。”

问题描述

嗨,我一直卡在 React FunctionuseState中。我只是想学习 hooks 和 useState,但即使努力寻找解决方案,我也无法取得任何进展。这是我的完整反应功能:

import React, { useState } from 'react';
import './MainPart.css';

function MainPart(props) {
  const [orderData_, setOrderData_] = useState(props.orderData);

  let topicData_ = props.topicData;
  let titleData_ = props.titleData;
  let infoData_ = props.infoData;

  return (
    <div className='MainPart'>
      <div className='mainWindow'>{getPics(orderData_)}</div>
      <div className='information'>
        <div className='moreNewsDivs'>
          <div className='moreNewsDiv1'>
            <h4>MORE NEWS</h4>
          </div>
          <div className='moreNewsDiv2'>
            <button
              className='previous-round'
              onClick={setOrderData_(previous(orderData_))}
            >
              &#8249;
            </button>
            &nbsp;&nbsp; &nbsp;&nbsp;
            <button href='/#' className='next-round'>
              &#8250;
            </button>
          </div>
        </div>
        <hr />
        <div className='topicDiv'>
          <h5 className='topicData'>{topicData_}</h5>
          <h5 className='titleData'>{titleData_}</h5>
          <h6 className='infoData'>{infoData_}</h6>
        </div>
      </div>
    </div>
  );
}

function previous(orderData_) {
  let newOrderData;

  if (orderData_ === 3) {
    newOrderData = 2;
    console.log(newOrderData);
    return newOrderData;
  } else if (orderData_ === 1) {
    newOrderData = 3;
    console.log(newOrderData);
    return newOrderData;
  } else {
    newOrderData = 1;
    console.log(newOrderData);
    return newOrderData;
  }
}

function next(orderData_) {
  let newOrderData;

  if (orderData_ === 3) {
    newOrderData = 1;
  } else if (orderData_ === 2) {
    newOrderData = 3;
  } else {
    newOrderData = 2;
  }
  return newOrderData;
}

const getPics = picOrder => {
  if (picOrder === 1) {
    return (
      <img
        src={require('../assets/desktopLarge/mainImage.png')}
        className='MainImage'
        alt=''
        id='mainImage'
      />
    );
  } else if (picOrder === 2) {
    return (
      <img
        src={require('../assets/desktopLarge/bridge.png')}
        className='MainImage'
        alt=''
        id='mainImage'
      />
    );
  } else {
    return (
      <img
        src={require('../assets/desktopLarge/forest.png')}
        className='MainImage'
        alt=''
        id='mainImage'
      />
    );
  }
};

export default MainPart;

我在使用useState. 即使加载页面新鲜并且没有按下任何我的按钮 onClick 事件侦听器激活,正如我之前在主题我的错误中提到的:

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

标签: reactjsreact-reduxreact-hooks

解决方案


问题可以在您的onClick道具中找到:

<button className="previous-round" onClick={setOrderData_(previous(orderData_))}>&#8249;</button>
                                            ^

花括号之间的所有内容都会立即进行评估。这会导致setOrderData_在每个渲染循环中调用该函数。

通过用箭头函数包装函数,评估的代码将生成一个函数,只要用户单击按钮,就可以调用该函数。

<button className="previous-round" onClick={() => setOrderData_(previous(orderData_))}
>&#8249;</button>

您可以在官方文档https://reactjs.org/docs/introducing-jsx.html#embedding-expressions-in-jsx中找到有关 JSX 和表达式的更多信息

无限重新渲染循环

无限循环的原因是因为setState事件回调中的某些东西(很可能)正在触发重新渲染。这将再次调用事件回调并导致 React 停止并抛出“Too many re-renders”。错误。

技术说明

为了更好地理解 JSX 以这种方式工作的原因,请参见下面的代码。JSX 实际上被编译为 Javascript,每个 prop 都将传递给 Object 中的一个函数。有了这些知识,您将看到handleEvent()在最后一个示例中立即调用了它。

// Simple example
// JSX: <button>click me</button>
// JS:  createElement('button', { children: 'click me' })
createElement("button", { children: "click me" });

// Correct event callback
// JSX: <button onClick={handleClick}>click me</button>
// JS:  createElement('button', { onClick: handleClick, children: 'click me' })
createElement("button", { onClick: handleClick, children: "click me" });

// Wrong event callback
// JSX: <button onClick={handleClick()}>click me</button>
// JS:  createElement('button', { onClick: handleClick(), children: 'click me' })
createElement("button", { onClick: handleClick(), children: "click me" });

推荐阅读