React.js useState钩子导致重新渲染太多,无法更新我的状态

时间:2020-04-26 07:56:25

标签: reactjs react-hooks rerender use-state

我是一名学生,试图摆脱React的困扰。到目前为止,我希望能够将从API接收到的数据数组切成大块,以便以后可以使用分页效果。我不知道为什么函数arrayChunk()最终导致太多渲染。如何设置我的函数以将chunkedArray推入setChunkedYearArray? 这是我的完整代码:

flex-basis

2 个答案:

答案 0 :(得分:1)

每次调用setState时,组件都会重新渲染,因此您无法在render函数中调用setState。没有理由为chunkedYearArray使用状态。只需从函数中返回值,然后使用它即可:

const InformationBoxLayout = props => {
  const [activeYear, setActiveYear] = useState([]);

  useEffect(() => {
    axios
      .get("http://www.mocky.io/v2/5ea446a43000005900ce2ca3")
      .then(response =>
        setActiveYear(
          response.data.timelineInfo.filter(item => item.year === "2018")
        )
      );
  }, []);

  const arrayChunk = (array, chunkSize) => {
    const chunkedArray = [];
    let clonedArray = [...array];
    const splitPieces = Math.ceil(clonedArray.length / chunkSize);
    for (let i = 0; i < splitPieces; i++) {
      chunkedArray.push(clonedArray.splice(0, chunkSize));
    }
    return chunkedArray;
  };

  // Now you have calculated it, so use it for whatever you want in your JSX
  const chunkedYearArray = activeYear.length > 6
        ? arrayChunk(activeYear, 6)
        : [];

  return (
    <div className={style.infoBoxLayoutStyle}>
      <button className={style.leftArrow}>
        <img src={arrowButton} alt="previous-page-button" />
      </button>


      <button className={style.rightArrow}>
        <img
          src={arrowButton}
          alt="next-page-button"
          className={style.rotateArrowRight}
        />
      </button>
    </div>
  );
};

export default InformationBoxLayout;

或者,如果您真正希望它处于状态,则可以从API调用中then进行计算:

  const [chunkedYearArray, setChunkedYearArray] = useState([]);
  useEffect(() => {
    axios
      .get("http://www.mocky.io/v2/5ea446a43000005900ce2ca3")
      .then(response =>
        setActiveYear(
          response.data.timelineInfo.filter(item => item.year === "2018")
        )

        const arrayChunk = (array, chunkSize) => {
          const chunkedArray = [];
          let clonedArray = [...array];
          const splitPieces = Math.ceil(clonedArray.length / chunkSize);
          for (let i = 0; i < splitPieces; i++) {
            chunkedArray.push(clonedArray.splice(0, chunkSize));
          }
          return chunkedArray;
        };

        const newChunkedYearArray = activeYear.length > 6 ? arrayChunk(activeYear, 6)
        : [];

        // Because we are in useEffect we are only calculated once!
        setChunkedYearArray(newChunkedYearArray)
      );
  }, []);

这里肯定有清理的空间,但是我认为其中任何一个都会使您走上正确的道路。希望有帮助!

答案 1 :(得分:0)

您最终在每个渲染阶段调用arrayChunk,从而设置了某些状态并触发了重新渲染。使用效果挂钩仅在activeYear更新时才重新计算分块数组。

useEffect(() => {
  activeYear.length > 6 && arrayChunk(activeYear, 6);
}, [activeYear]);

然后仅渲染{ chunkedYearArray }