【问题标题】:React JS - Component rendering in infinite loopReact JS - 无限循环中的组件渲染
【发布时间】:2021-10-24 03:01:20
【问题描述】:

当我使用 Bar 组件渲染屏幕时,它会无限循环地渲染,甚至在我尝试传递数据之前。 我已经导入 react-chartjs-2 进行测试,效果很好,即只加载一次。但是另一个条形图似乎会呈现,然后继续这样做,直到我的浏览器崩溃。

我认为这可能与我的组件是 const 的事实有关。

//import Bar from 'react-chartjs-2';   // <-- Renders once
import Bar from './../charts/Bar.js';  // <-- Renders in a loop

const MyComponent = () => {

    return (
        <div className="search">
            <Bar/>
        </div>
    );

}
export default MyComponent;

这是我正在使用的 Bar 组件。它来自名为 Gogo-React 的 Themeforest 模板。

/* eslint-disable prefer-rest-params */
import React, { useEffect, useRef, useState } from 'react';
import { Chart } from 'chart.js';

import { barChartOptions } from './config';

const Bar = ({ data, shadow = false }) => {
  const chartContainer = useRef(null);
  const [, setChartInstance] = useState(null);

  useEffect(() => {
    if (chartContainer && chartContainer.current) {
      if (shadow) {
        Chart.defaults.global.datasets.barWithShadow =
          Chart.defaults.global.datasets.bar;
        Chart.defaults.barWithShadow = Chart.defaults.bar;
        Chart.controllers.barWithShadow = Chart.controllers.bar.extend({
          draw(ease) {
            Chart.controllers.bar.prototype.draw.call(this, ease);
            const {
              chart: { ctx },
            } = this;
            ctx.save();
            ctx.shadowColor = 'rgba(0,0,0,0.2)';
            ctx.shadowBlur = 7;
            ctx.shadowOffsetX = 5;
            ctx.shadowOffsetY = 7;
            ctx.responsive = true;
            Chart.controllers.bar.prototype.draw.apply(this, arguments);
            ctx.restore();
          },
        });
      }
      const context = chartContainer.current.getContext('2d');
      const newChartInstance = new Chart(context, {
        type: shadow ? 'barWithShadow' : 'bar',
        options: barChartOptions,
        data,
      });
      setChartInstance(newChartInstance);
    }
  }, [chartContainer, data, shadow]);

  return <canvas ref={chartContainer} />;
};

export default Bar;

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    useEffect 正在监听 chartContainer。然后 useEffect 正在运行并更改画布和 chartContainer ref,然后触发 useEffect。 这将导致循环。

    【讨论】:

    • 我调用 Bar 组件的方式有问题吗?我试图避免编辑它,因为它是我正在使用的模板的一部分,我认为它可以工作。这可能是由我调用组件的上下文引起的吗?
    【解决方案2】:

    React 中的 useEffect() 钩子在每次依赖关系状态发生变化时都会被调用,因为 chartContianer 状态正在更新,你的 bar 会重复调用 useEffect() 钩子。

    更好的方法是更新图表中的数据,而不是更新整个图表本身。

    【讨论】:

    • 我调用 Bar 组件的方式有问题吗?我试图避免编辑它,因为它是我正在使用的模板的一部分,我认为它可以工作。这可能是由我调用组件的上下文引起的吗?
    猜你喜欢
    • 2019-01-07
    • 2020-10-22
    • 2021-02-26
    • 2018-08-08
    • 2016-02-29
    • 2010-12-24
    • 2020-04-14
    • 1970-01-01
    • 2017-10-19
    相关资源
    最近更新 更多