超过最大更新深度。反应useEffect

时间:2020-01-16 01:31:03

标签: javascript reactjs react-hooks

我在下面的组件中收到以下错误。奇怪的是,仅当我更改文件中的某些内容(例如更改默认属性)并将某些内容保存在文件中时,才会发生这种情况。我需要依靠启动重新渲染的道具,因为物品列表正在由过滤器更新。

Blockquote 当组件在useEffect中调用setState时会发生这种情况,但useEffect要么没有依赖项数组,要么在每个渲染器上都有一个依赖项更改。

这是组件代码:

import React, { useState, useEffect } from 'react';
import classNames from 'classnames';

import Button from '../Button';

const nsBase = 'component';

const ns = `${ nsBase }-content-feed`;

const ContentFeed = (props) => {
  const {
    showAllItems,
    items,
    nextVisibleAmount,
    ItemView,
    loadButton
  } = props;

  let {
    initialVisibleAmount
  } = props;

  const {
    label
  } = loadButton;

  // if showAllItems display all items in items array
  if (showAllItems) {
    initialVisibleAmount = items.length;
  }

  const [visible, setVisible] = useState(initialVisibleAmount);
  const [visibleItems, setvisibleItems] = useState([...items]);

  useEffect(() => {
    setvisibleItems([...props.items]);

    if (props.items.length < initialVisibleAmount) {
      setVisible(props.items.length);
    } else {
      setVisible(initialVisibleAmount);
    }
  }, [props, initialVisibleAmount]);


  const handleLoadMore = () => {
    setVisible((prevState) => {
      return (prevState + nextVisibleAmount);
    });
  };

  const rootClassnames = classNames({
    [`${ ns }`]: true
  });

  return (
    <div className={rootClassnames}>
      {visibleItems.slice(0, visible).map((item, index) => {
        return <ItemView key={item.id} article={item} index={index} />;
      })}
      {(visible < visibleItems.length) && (
        <div className={`${ ns }__load-more`}>
          <Button onClick={handleLoadMore}><h4>{label}</h4></Button>
        </div>
      )}
    </div>
  );
};

export default ContentFeed;

ContentFeed.defaultProps = {
  showAllItems: false,
  items: [],
  initialVisibleAmount: 3,
  nextVisibleAmount: 3,
  ItemView: () => {
    return <div>Item View Default</div>;
  },
  loadButton: {
    label: 'More'
  }
};

1 个答案:

答案 0 :(得分:0)

在使用效果挂钩中添加一些检查。由于useEffect第一行总是更新状态,因此将导致无限循环。状态的任何更改都将执行useEffect钩子,因为它取决于props, initialVisibleAmoun

尝试这样的事情。

 useEffect(() => {
        if(props.items !== visibleItems) {
            setvisibleItems([...props.items]);
        }

        if(props.items.length !== visible) {
            if (props.items.length < initialVisibleAmount) {
                setVisible(props.items.length);
            } else {
                setVisible(initialVisibleAmount);
            }
        }

    }, [props, initialVisibleAmount]);