【问题标题】:Too many re-renders with React Hooks and Redux使用 React Hooks 和 Redux 重新渲染的次数过多
【发布时间】:2019-11-23 22:53:33
【问题描述】:

我有一个显示卡片列表的组件。我正在尝试对表格行进行排序,但遇到了一些问题。当我转到该页面时,我收到以下错误:

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

它指向这条线

setData(_.sortBy(filteredData.reverse()));

这是我的完整组件代码。任何人都可以看到我正在尝试做的事情有问题吗?

import React, { useState } from "react";
import Search from "./Search";
import TimeAgo from "react-timeago";
import { useSelector, useDispatch, connect } from "react-redux";
import { Table } from "semantic-ui-react";
import { searchChange } from "../reducers/searchReducer";
import _ from "lodash";
// import { useField } from "../hooks";

const searchCards = ({ baseball, search }) => {
  return search
    ? baseball.filter(a =>
        a.title[0].toLowerCase().includes(search.toLowerCase())
      )
    : baseball;
};

const Cards = props => {
  const [column, setColumn] = useState(null);
  const [direction, setDirection] = useState(null);
  const [filteredData, setData] = useState(props.cardsToShow);

  const handleSort = clickedColumn => {
    if (column !== clickedColumn) {
      setColumn(clickedColumn);
      setData(_.sortBy(filteredData, [clickedColumn]));
      setDirection("ascending");
      return;
    }

    setData(_.sortBy(filteredData.reverse()));
    direction === "ascending"
      ? setDirection("descending")
      : setDirection("ascending");
  };

  return (
    <>
      <div>
        <Search />
        <h3>Vintage Card Search</h3>
        <Table sortable celled fixed striped>
          <Table.Header>
            <Table.Row>
              <Table.HeaderCell
                sorted={column === "title" ? direction : null}
                onClick={handleSort("title")}
              >
                Card Title
              </Table.HeaderCell>
              <Table.HeaderCell># Bids</Table.HeaderCell>
              <Table.HeaderCell>Watchers</Table.HeaderCell>
              <Table.HeaderCell>Price</Table.HeaderCell>
              <Table.HeaderCell>Time Left</Table.HeaderCell>
            </Table.Row>
          </Table.Header>
          <Table.Body>
            {props.cardsToShow.map(card => (
              <>
                <Table.Row key={card.id}>
                  <Table.Cell>{card.title}</Table.Cell>
                  <Table.Cell>
                    {card.sellingStatus[0].bidCount
                      ? card.sellingStatus[0].bidCount
                      : 0}
                  </Table.Cell>
                  <Table.Cell>
                    {card.listingInfo[0].watchCount
                      ? card.listingInfo[0].watchCount
                      : 0}
                  </Table.Cell>
                  <Table.Cell>
                    $
                    {card.sellingStatus &&
                      card.sellingStatus[0].currentPrice[0]["__value__"]}
                  </Table.Cell>
                  <Table.Cell>
                    <TimeAgo
                      date={new Date(
                        card.listingInfo && card.listingInfo[0].endTime
                      ).toLocaleDateString()}
                    />
                  </Table.Cell>
                </Table.Row>
              </>
            ))}
          </Table.Body>
        </Table>
      </div>
    </>
  );
};

const mapStateToProps = state => {
  return {
    baseball: state.baseball,
    search: state.search,
    cardsToShow: searchCards(state)
  };
};

const mapDispatchToProps = {
  searchChange
};

export default connect(mapStateToProps, mapDispatchToProps)(Cards);
// export default Cards;

【问题讨论】:

    标签: javascript reactjs react-redux lodash


    【解决方案1】:

    Yachaka 已经指出了错误的行,但他们的回答并没有说明问题所在。

    当你在 React 中使用 prop={expression} 传递 props 时,括号中的表达式会被评估,就像函数参数在传递时被评估一样。因此,每当渲染组件时,都会调用handleSort("title")。然后这个函数会导致 props 被更新,组件被重新渲染,导致循环无限重复。

    所以问题在于,您调用该函数(使用handleSort("title"))而不是传递一个应该在单击按钮时调用的函数,这会导致undefined,并导致反馈循环。

    相反,您应该使用返回函数的表达式。正如 Yachaka 提到的 () =&gt; handleSort("title"),在 JavaScript 中最简洁的方法是箭头函数。这将评估为调用 handleSort 的函数。

    【讨论】:

    • 感谢您提供的超级有用的解释。我很高兴你写了这篇文章,因为我有点不确定为什么
    【解决方案2】:

    改变这一行:

    onClick={handleSort("title")}
    

    通过

    onClick={() => handleSort("title")}
    

    编辑:Reinis 在下面写了一个很好的解释!

    【讨论】:

      猜你喜欢
      • 2020-02-23
      • 1970-01-01
      • 1970-01-01
      • 2020-11-27
      • 1970-01-01
      • 1970-01-01
      • 2020-01-07
      • 1970-01-01
      • 2021-09-09
      相关资源
      最近更新 更多