简体   繁体   中英

How to access React hook state in Highcharts event listener

I'm trying to update state in an event listener using React hooks by adding to the existing state:

import React, { useState } from 'react';
import { render } from 'react-dom';
import HighchartsReact from 'highcharts-react-official';
import Highcharts from 'highcharts';

const LineChart = () => {
  const [hoverData, setHoverData] = useState(null);
  const [hoveredOverCategories, setHoveredOverCategories] = useState([]);
  const [chartOptions, setChartOptions] = useState({
    xAxis: {
      categories: ['A', 'B', 'C'],
    },
    series: [
      { data: [1, 2, 3] }
    ],
    plotOptions: {
      series: {
        point: {
          events: {
            mouseOver(e){
              console.log(hoveredOverCategories); // Always prints the empty array `[]`
              setHoverData(e.target.category);
              setHoveredOverCategories(
                [...hoveredOverCategories, e.target.category]
              );
            }
          }
        }
      }
    }
  });

  return (
      <div>
        <HighchartsReact
          highcharts={Highcharts}
          options={chartOptions}
        />
        <h3>Hovering over {hoverData}</h3>
        <ol>
          {hoveredOverCategories.map(category => (
            <li>Hovered over {category}</li>
          ))}
        </ol>
      </div>
    )
}

render(<LineChart />, document.getElementById('root'));

However, it seems like the event listener ( mouseOver ) doesn't have access to updated state ( hoveredOverCategories ): console.log(hoveredOverCategories); always prints the empty array [] .

The expected result is that the array of categories is added to for each mouseOver event. See this demonstration . But what actually happens is that the array is overwritten with only the most recent value.

(This reproduction is based on the documented optimal way to update , demonstrated here .)

Note that I was able to get the expected results using a class component.

I think that accessing the hoveredCategories via closure isn't the more precise one. I was able to make it work by accessing it using the previous state instead of relying on the closure value:

mouseOver(e){
  console.log(hoveredOverCategories);
  setHoverData(e.target.category);
  setHoveredOverCategories((prevHoveredOverCategories) => {
    return [...prevHoveredOverCategories, e.target.category]
  });
}

Have a look at it working: https://stackblitz.com/edit/highcharts-react-hook-state-event-listener-xxqscw

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM