Yngve Høiseth
Yngve Høiseth

Reputation: 590

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.

Upvotes: 0

Views: 1108

Answers (1)

cefeboru
cefeboru

Reputation: 332

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

Upvotes: 1

Related Questions