在反应挂钩中,我如何将过滤后的值传递给图表?

In react hooks, how can i pass the filtered values to the chart?

我正在使用带有钩子的 React 将过滤后的值传递给图表。 问题是我无法将“filterData”值传递给图表:

const filterData = data.datasets[0].data.filter(value => value > Number(filterdatanumber))

关于如何解决这个问题有什么建议吗? 我已经尝试了这些视频中存在的不同解决方案 https://www.youtube.com/watch?v=cz2rG-OVXXU,或者创建了一个新变量等等,但是没有任何效果。

完整代码:

import React, { useState } from 'react';
import { Bar } from 'react-chartjs-2';

export default function VerticalBar() {
  const [firstNumber, setFirstNumber] = useState("");
    const textChangeHandler = (i) => {
    setFirstNumber(i.target.value);
    console.log("target.value", i.target.value);
    filterChart(Number(i.target.value)); 
  };

    const data = {
      labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
      datasets: [{
        label: 'Weekly Sales',
        data: [18, 12, 6, 9, 11, 3, 9],
        backgroundColor: [
          'rgba(255, 26, 104, 0.2)',
          'rgba(54, 162, 235, 0.2)',
          'rgba(255, 206, 86, 0.2)',
          'rgba(75, 192, 192, 0.2)',
          'rgba(153, 102, 255, 0.2)',
          'rgba(255, 159, 64, 0.2)',
          'rgba(0, 0, 0, 0.2)'
        ],
        borderColor: [
          'rgba(255, 26, 104, 1)',
          'rgba(54, 162, 235, 1)',
          'rgba(255, 206, 86, 1)',
          'rgba(75, 192, 192, 1)',
          'rgba(153, 102, 255, 1)',
          'rgba(255, 159, 64, 1)',
          'rgba(0, 0, 0, 1)'
        ],
        borderWidth: 1
      }]
    };
    
    const filterChart = (filterdatanumber = Number.MIN_SAFE_INTEGER) => {
      const filterData = data.datasets[0].data.filter(value => value > Number(filterdatanumber))
      // const filterData = data.datasets[0].data.filter(value => value > 9)

      const filterLabels = [];
      const filterColors = [];
      let i = 0;
      for (i; i < filterData.length; i++) {
        const result = data.datasets[0].data.indexOf(filterData[i]);
        const labelsResult = data.labels[result];
        const colorssResult = data.datasets[0].backgroundColor[result];
        filterLabels.push(labelsResult );
        filterColors.push(colorssResult);
    }
    
    console.log("filterData", filterData)
    console.log("filterLabels", filterLabels)
    console.log("filterColors",filterColors)

    data.datasets[0].data = filterData;
    data.labels = filterLabels;
    data.datasets[0].backgroundColor = filterColors;
  }
  filterChart();

    return (
      <div >
       <Bar  data={data} />
       <input value={firstNumber} type="number" name="firstNumber" onChange={textChangeHandler} />
      </div>
    )
}

关于如何处理组件内的状态日期,您的代码存在很多问题。

如果 data 不变,那么您可以将其移出组件。

函数 filterData 可以替换为保存过滤数据的状态和将在另一个 filterdatanumber 状态更改时触发的 useEffect

这是一个包含这些更改的示例代码。

import React, { useState, useEffect } from "react";
import { Bar } from "react-chartjs-2";

const data = {
  labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
  datasets: [
    {
      label: "Weekly Sales",
      data: [18, 12, 6, 9, 11, 3, 9],
      backgroundColor: [
        "rgba(255, 26, 104, 0.2)",
        "rgba(54, 162, 235, 0.2)",
        "rgba(255, 206, 86, 0.2)",
        "rgba(75, 192, 192, 0.2)",
        "rgba(153, 102, 255, 0.2)",
        "rgba(255, 159, 64, 0.2)",
        "rgba(0, 0, 0, 0.2)",
      ],
      borderColor: [
        "rgba(255, 26, 104, 1)",
        "rgba(54, 162, 235, 1)",
        "rgba(255, 206, 86, 1)",
        "rgba(75, 192, 192, 1)",
        "rgba(153, 102, 255, 1)",
        "rgba(255, 159, 64, 1)",
        "rgba(0, 0, 0, 1)",
      ],
      borderWidth: 1,
    },
  ],
};

export default function VerticalBar() {
  const [firstNumber, setFirstNumber] = useState("");
  const [filterdatanumber, setFilterdatanumber] = useState(
    Number.MIN_SAFE_INTEGER
  );
  const [filteredData, setFilteredData] = useState(data);
  const textChangeHandler = (i) => {
    setFirstNumber(i.target.value);
    console.log("target.value", i.target.value);
    filterChart(Number(i.target.value));
  };

  useEffect(() => {
    const newData = { ...data };
    const filteredData = [];
    const filterLabels = [];
    const filterColors = [];
    for (let i = 0; i < newData.datasets[0].data.length; i++) {
      const value = newData.datasets[0].data[i]
      if (value > Number(filterdatanumber)) {
        const labelsResult = newData.labels[i];
        const colorssResult = newData.datasets[0].backgroundColor[i];
        filterLabels.push(labelsResult);
        filterColors.push(colorssResult);
        filteredData.push(value)
      }
    }
    console.log("filteredData", filteredData);
    console.log("filterLabels", filterLabels);
    console.log("filterColors", filterColors);
    newData.datasets[0].data = filteredData;
    newData.labels = filterLabels;
    newData.datasets[0].backgroundColor = filterColors;
    setFilteredData(newData);
  }, [filterdatanumber]);

  return (
    <div>
      <Bar data={filteredData} />
      <input
        value={firstNumber}
        type="number"
        name="firstNumber"
        onChange={textChangeHandler}
      />
    </div>
  );
}

请记住,此代码只是一个示例,可能需要进行一些编辑才能满足您的需求。

这是我的最终解决方案,它完全有效,并且采用了重构的第三种方法。在过滤并在图表中正确显示时,这些值始终与键匹配。

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Bar } from "react-chartjs-2";

export default function VerticalBar() {
  const [data, setData] = useState ([
    {val: 18, label: "Mon"},
    {val: 1, label: "Tue"},
    {val: 5, label: "Wed"}, 
    {val: 8, label: "Thu"}, 
    {val: 19, label: "Fri"}, 
    {val: 5, label: "Sat"}, 
    {val: 7, label: "Sun"}
  ])

  const chartConfig = useMemo(() => {
    return  {
        labels: data.map(el => el.label), 
        datasets: [
          {
            label: "Weekly Sales",
            data: data.map(el => el.val),
            backgroundColor: [
              "rgba(255, 26, 104, 0.2)",
              "rgba(54, 162, 235, 0.2)",
              "rgba(255, 206, 86, 0.2)",
              "rgba(75, 192, 192, 0.2)",
              "rgba(153, 102, 255, 0.2)",
              "rgba(255, 159, 64, 0.2)",
              "rgba(0, 0, 0, 0.2)",
            ],
            borderColor: [
              "rgba(255, 26, 104, 1)",
              "rgba(54, 162, 235, 1)",
              "rgba(255, 206, 86, 1)",
              "rgba(75, 192, 192, 1)",
              "rgba(153, 102, 255, 1)",
              "rgba(255, 159, 64, 1)",
              "rgba(0, 0, 0, 1)",
            ],
            borderWidth: 1,
          },
        ],
      };
    
  }, [data])

  const textChangeHandler = useCallback(
    (event) => {
    setData(prevData => {
      return prevData.filter((el) => parseInt(event.target.value, 10) < el.val)
    })
  }, [setData]);

  return (
    <div>
      <Bar data={chartConfig} />
      <input
        type="number"
        name="firstNumber"
        onChange={textChangeHandler}
      />
    </div>
  );
}