React,Typescript - 根据状态数量动态渲染组件数量

时间:2021-02-21 16:19:40

标签: reactjs typescript

我正在构建一个 React 应用程序,它需要根据输入字段中的数字显示一定数量的折线图。该数字从上一页作为“chartCount”传递。每个图表都需要“dataPoints”数量的数据点。我能够将正确的数据发送到控制台,并且可以正确地获取 1 个图表。问题是我需要创建多个图表。当我发现如何制作多个图表时,它使用相同的数组,而不是为每个图表使用单独的 API 调用。我需要能够在每个图表中放置不同的数组。

我正在使用 rechart 绘制图表。

hasCycled

1 个答案:

答案 0 :(得分:0)

因此,您实际上需要根据需要渲染组件的次数。 我能想到的最简单的方法是根据您的 chartCount 道具创建一个数字数组。应该看起来像这样:

    const numberToIterable = (n) => {
      const arr = []
      
      for (let i=0; i<n; i++) {
        arr.push(i)
      }
      
      return arr
    }

然后您可以使用它根据需要多次渲染您的组件:

return (
  <div>
     {numberToIterable(chartCount).map((x) => <LineRechartComponent chartData={chartData} />)}
  </div>
)

但是,我确实注意到您有一个调用来获取与 chartCount 匹配的数据点。因此,您可能不需要我上面建议的任何内容,而是使用 getDataPoints 函数从需要呈现的所有图表中获取所有必要的数据。

首先,让我们修正您在 chartData 中的 useEffect 设置。不是每次迭代都做,而是在迭代完成后只做一次。更改应该使该代码看起来像这样:

      React.useEffect(() => {
        const data = []
        if (chartCount && dataPoints) {
          if (chartCount > 0 && dataPoints > 0) {
            let i = 0;
            while (i < chartCount) {
              data.push(getDataPoints(dataPoints, i));

              i++;
            }
            // Set the state only once per iteration instead of doing so inside `getDataPoints`
            setChartData(data)
          }
        }
      
      }, [chartCount, dataPoints])

现在,您可以将该信息用于渲染中的 .map 并根据需要多次渲染 LineRechartComponent

...
 return (
        <div>
          {chartData.map((data) => (
            <LineRechartComponent chartData={data}/>
          ))}
        </div>
      )

这是一个工作示例应用程序,其中包含示例数据来说明这一点:

const LineRechartComponent = ({ chartData }) => {
  console.warn('CHART DATA', chartData);
  return (
    <div>LineRechartComponent Component --> {chartData[0].data}</div>
  )
}

const App = ({ chartCount, dataPoints }) => {
  const [chartData, setChartData] = React.useState([]);
  
  const getDataPoints =  (dataPoints, i) => {
    // Continue doing all your API stuff here
    const jsonData = [{ data: `Example data from ${i} for data points ${dataPoints}` }]
    
    return jsonData
  }
  
  React.useEffect(() => {
    const data = []
    if (chartCount && dataPoints) {
      if (chartCount > 0 && dataPoints > 0) {
        let i = 0;
        while (i < chartCount) {
          data.push(getDataPoints(dataPoints, i));

          i++;
        }
        // Set the state only once per iteration
        setChartData(data)
      }
    }
  
  }, [chartCount, dataPoints])
  
  console.warn('Test', chartData)

  return (
    <div>
      {chartData.map((i) => (
        <LineRechartComponent chartData={i}/>
      ))}
    </div>
  )
}


ReactDOM.render(
    <App chartCount={5} dataPoints={5} />,
    document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>