Как управлять не-React компонентом (BokehJS) в React? - PullRequest
0 голосов
/ 03 мая 2019

Предыстория
Я хочу включить график BokehJS в свой компонент React.Процесс для этого состоит в том, чтобы визуализировать <div id="my_plot_id" className="bk-root"/> и вызвать window.Bokeh.embed.embed_item(plotData, 'my_plot_id'), который вводит необходимый HTML в DOM.

Поскольку я хочу управлять графиком BokehJS, используя состояние компонента React (т.е. заменить график новым сгенерированнымданные графика), я не хочу просто звонить embed_item() в componentDidMount().Вместо этого я поместил embed_item() в render() и добавил некоторый код для удаления дочерних узлов контейнера div перед этим вызовом.

Проблема
Мой компонент React визуализируется 3 раза при загрузке страницы, и хотя при окончательном рендеринге у меня отображается только один график, существует короткий момент (я думаю, что между 2-м и 2-м3-й / последний рендер), где я вижу два графика.

Код

render()
  {
    let plotNode = document.getElementById('my_plot_id');    
    console.log(plotNode && plotNode.childElementCount);

    while (plotNode && plotNode.firstChild) {
      //remove any children
      plotNode.removeChild(plotNode.firstChild);
    }

    const { plotData } = this.state;
    window.Bokeh.embed.embed_item(plotData, 'my_plot_id');

    return(
      <div id="my_plot_id" className="bk-root"/>
    )
  }

В консоли я вижу:

null
0
2

Вопрос
Похоже, что embed_item выполняется дважды, прежде чем my_plot_id дети будут правильно обнаружены.

Почему это происходит и как я могу решить это?Хотя тройной рендеринг не может быть оптимизирован по производительности, я полагаю, что мой компонент должен рендерить рендеринг так часто, как это необходимо (в пределах разумного), без визуальных сбоев, подобных этому, поэтому я не сосредоточил свои мысли на способах предотвращения повторного рендеринга.рендеринга.

Ответы [ 2 ]

0 голосов
/ 03 мая 2019

При запуске plotNode не может достичь 'my_plot_id'.

Вы можете отобразить null при запуске, когда plotData недоступно.

Вы можете использовать componentDidUpdate().

В этом случае я бы попытался shouldComponentUpdate() - обновить узел DOM и вернуть false, чтобы избежать повторного рендеринга.

0 голосов
/ 03 мая 2019

Взаимодействие с элементами DOM должно никогда происходить внутри метода render.Вы должны запустить библиотеку элемента, используя метод жизненного цикла componentDidMount, обновить его на основе реквизитов, используя componentDidUpdate, и уничтожить, используя componentWillUnmount.

Официальная документация React имеетпример использования jQuery, который показывает вам, как обращаться с другими библиотеками dom.

...