Как я могу передать значения из обратных вызовов событий Highcharts (щелчок, наведение курсора мыши, mouseOut) обратно в функцию-член компонента React?

#javascript #reactjs #highcharts #this

#javascript #reactjs #highcharts #это

Вопрос:

Я могу создать диаграмму и передать функцию для mouseOver события, которая просто регистрирует значения x и y маркера, на который я наводлю курсор:

 // Works

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

class App extends React.Component {

  render = () => {
    const options = {
      chart: {
        type: 'spline'
      },
      title: {
        text: 'My chart'
      },
      series: [
        {
          data: [1, 2, 1, 4, 3, 6]
        }
      ],
      plotOptions: {
        series: {
          point: {
            events: {
              mouseOver: function () {
                const point = { x: this.x, y: this.y };
                console.log(point);
              }
            }
          }
        }
      }
    };

    return (
      <div>
        <HighchartsReact highcharts={Highcharts} options={options} />
      </div>
    )
  }
}

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

В конечном счете я хочу иметь возможность передавать это point обратно моему компоненту и использовать его в другом месте моего приложения.

Простая идея вызова функции в моем компоненте из события не работает — this то, что я передаю в plotOptions , больше относится не к моему компоненту, а к точке на диаграмме:

 // Does not work
// Uncaught TypeError: this.handleMouseOver is not a function

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

class App extends React.Component {

  handleMouseOver = point => {
    console.log(`handleMouseOver gets ${point}`);
  }

  render = () => {
    const options = {
      chart: {
        type: 'spline'
      },
      title: {
        text: 'My chart'
      },
      series: [
        {
          data: [1, 2, 1, 4, 3, 6]
        }
      ],
      plotOptions: {
        series: {
          point: {
            events: {
              mouseOver: function () {
                const point = { x: this.x, y: this.y };
                this.handleMouseOver(point);                 <--- not the `this` of my component
              }
            }
          }
        }
      }
    };

    return (
      <div>
        <HighchartsReact highcharts={Highcharts} options={options} />
      </div>
    )
  }
}

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

Неудивительно, что ошибка, которую я получаю в браузере при наведении курсора мыши на точку, является

 Uncaught TypeError: this.handleMouseOver is not a function
  

Есть предложения?

Спасибо.

Комментарии:

1. Одно из решений, которое я нашел, — поместить const foo = this.handleMouseOver; в начало render функции и вызвать foo(point) в plotOptions . Это позволяет избежать использования this в plotOptions для ссылки на компонент. Хотя это немного похоже на обман. Есть ли что-нибудь более элегантное?

Ответ №1:

Вы можете достичь этого с помощью одного из этих решений:

1) сохраните ссылку на компонент в объекте диаграммы следующим образом:

 componentDidMount() {
  this.chart = this.refs.chart.chart;
  this.chart.component = this;
}
  

И использовать это внутри mouseOver обратного вызова:

 plotOptions: {
  series: {
    point: {
      events: {
        mouseOver: function() {
          const self = this.series.chart.component;
          const point = {
            x: this.x,
            y: this.y
          };

          self.handleMouseOver(point);
        }
      }
    }
  }
}
  

ДЕМОНСТРАЦИЯ:


2) используйте IIFE, чтобы сохранить ссылку на объект component, а затем использовать ее внутри mouseOver функции обратного вызова:

 plotOptions: {
  series: {
    point: {
      events: {
        mouseOver: (function(self) {
          return function() {
            const point = {
              x: this.x,
              y: this.y
            };
            self.handleMouseOver(point);
          };
        })(this)
      }
    }
  }
}
  

ДЕМОНСТРАЦИЯ:

Комментарии:

1. Можно ли использовать тот же шаблон для события on click вместо наведения курсора мыши??

2. Да, тот же шаблон может быть использован для click события.

3. что, если мой компонент диаграммы является функциональным компонентом, и я не могу его использовать? кроме того, я определил свой chartOption в другом файле, например chartConfig.js . и экспортировать это в мой компонент диаграммы. Меня также смутила эта строка: ` const point = { x: this.x, y: this.y };` . откуда берутся this.x и this.y?