【问题标题】:React giving me Error: Too many re-renders. React limits the number of renders to prevent an infinite loop反应给我错误:重新渲染太多。 React 限制渲染次数以防止无限循环
【发布时间】:2021-04-06 17:30:03
【问题描述】:

handleSortByChange 函数在浏览器上给我一个错误,指出“重新渲染太多。 React 限制了渲染的数量以防止无限循环。”但是在终端上却提示编译成功

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

const sortByOptions = {
    'Best Match': 'best_match',
    'Highest Rated': 'rating',
    'Most Reviewed': 'review_count'
}

function SearchBar() {
    const [ sortBy, setSortBy ] = useState('best_match')

    const getSortByClass = (sortByOption) => {
        if(sortBy === sortByOption) {
            return 'active';
        } else {
            return '';
        }
    }

    const handleSortByChange = (sortByOption) => {
        setSortBy(sortByOption);
    }

    const renderSortByOptions = () => {
        return Object.keys(sortByOptions).map((sortByOption) => {
            let sortByOptionValue = sortByOptions[sortByOption];
            return <li onClick={handleSortByChange(sortByOptionValue)} className={getSortByClass(sortByOptionValue)} key={sortByOptionValue}>{sortByOption}</li>
        })
    }

    return(
        <div className="SearchBar">
            <div className="SearchBar-sort-options">
                <ul>
                    {renderSortByOptions()}
                </ul>
            </div>
            <div className="SearchBar-fields">
                <input placeholder="Search Businesses" />
                <input placeholder="Where?" />
            </div>
            <div className="SearchBar-submit">
                {/* <a href="#">Let's Go</a> */}
                {/* <button>Let's Go</button> */}
            </div>
        </div>
    )
}

export default SearchBar;

【问题讨论】:

  • 您应该注意的一件事是成功的编译/构建并不等同于 0 个运行时错误。无限循环渲染是运行时错误。 React 构建过程无法知道您的编程逻辑是否会无限渲染组件;至少当前版本是这样。

标签: reactjs function components render infinite-loop


【解决方案1】:

在你的&lt;li&gt; 标签上,你直接调用了类似的方法,

onClick={handleSortByChange(sortByOptionValue)},它将设置状态并触发重新渲染,同样的事情也会在这个渲染周期中再次发生,从而无限循环。

改为执行以下操作:

<li
          onClick={()=>handleSortByChange(sortByOptionValue)}
          className={getSortByClass(sortByOptionValue)}
          key={sortByOptionValue}
        >

这样,handleSortByChange(sortByOptionValue) 只会在&lt;li&gt; 元素被点击时才会被执行。

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

const sortByOptions = {
  "Best Match": "best_match",
  "Highest Rated": "rating",
  "Most Reviewed": "review_count"
};

function SearchBar() {
  const [sortBy, setSortBy] = useState("best_match");

  const getSortByClass = sortByOption => {
    if (sortBy === sortByOption) {
      return "active";
    } else {
      return "";
    }
  };

  const handleSortByChange = sortByOption => {
    setSortBy(sortByOption);
  };

  const renderSortByOptions = () => {
    return Object.keys(sortByOptions).map(sortByOption => {
      let sortByOptionValue = sortByOptions[sortByOption];
      return (
        <li
          onClick={()=>handleSortByChange(sortByOptionValue)}
          className={getSortByClass(sortByOptionValue)}
          key={sortByOptionValue}
        >
          {sortByOption}
        </li>
      );
    });
  };

  return (
    <div className="SearchBar">
      <div className="SearchBar-sort-options">
        <ul>{renderSortByOptions()}</ul>
      </div>
      <div className="SearchBar-fields">
        <input placeholder="Search Businesses" />
        <input placeholder="Where?" />
      </div>
      <div className="SearchBar-submit">
       
      </div>
    </div>
  );
}

export default SearchBar;

工作示例:Stackblitz

【讨论】:

  • 在您的原始代码中,甚至在&lt;li/&gt; onClick 中,您直接调用函数handleSortByChange(sortByOptionValue),一旦应用程序被渲染,该函数将执行并更改状态并触发下一次重新渲染,同样的事情发生在新的重新渲染中并且循环继续。
  • 在给定的解决方案中,我们正在执行&lt;li onClick={()=&gt;handleSortByChange(sortByOptionValue)}..,其中handleSortByChange(sortByOptionValue) 在点击事件发生之前不会被执行。
  • 非常感谢。这很有意义!
【解决方案2】:

在 onClick 函数上试试这个:

{() => onClick={handleSortByChange(sortByOptionValue)}

【讨论】:

    猜你喜欢
    • 2020-09-11
    • 2021-05-17
    • 2021-02-04
    • 2021-07-01
    • 2021-10-21
    • 2020-08-06
    • 2021-10-21
    • 1970-01-01
    • 2021-02-26
    相关资源
    最近更新 更多