Текст пользовательской кнопки экспорта становится неопределенным при использовании useEffect в Canvasjs

https://stackblitz.com/edit/vitejs-vite-myutvi?file=src%2FApp.jsx

Привет,

В настоящее время я интегрирую пользовательскую функцию экспорта. Моя цель — добавить кнопку экспорта для отображения «Сохранить как CSV», но текст отображается как неопределенный.

import React, { useEffect, useState } from 'react';
import CanvasJSReact from '@canvasjs/react-charts';

const { CanvasJSChart } = CanvasJSReact;

function Chart({ isLoading, data }) {
  // Default chart options setup
  const defaultOptions = {
    animationEnabled: true,
    exportEnabled: true,
    theme: 'dark2',
    // Additional options...
  };

  const [chartOptions, setChartOptions] = useState(defaultOptions);

  useEffect(() => {
    // Conditional logic based on <code>isLoading</code> and <code>data</code>
    if (isLoading) {
      setChartOptions({ ...defaultOptions, /* Loading state */ });
    } else if (data?.length > 0) {
      setChartOptions({ ...defaultOptions, /* Data available state */ });
    } else {
      setChartOptions({ ...defaultOptions, /* No data state */ });
    }
  }, [isLoading, data]);

 
  return (
    <CanvasJSChart
      options = {chartOptions}
      onRef = {(chart) => {
        if (chart?.get("exportEnabled")) {
          const text = document.createTextNode("Save as CSV");
          const exportCSV = document.createElement("div");
          exportCSV.appendChild(text);
          exportCSV.setAttribute('style', <code>padding: 12px 8px; background-color: ${chart.toolbar.itemBackgroundColor}; color: ${chart.toolbar.fontColor}</code>);
          exportCSV.addEventListener('mouseover', () => {
            exportCSV.setAttribute('style', <code>padding: 12px 8px; background-color: ${chart.toolbar.itemBackgroundColorOnHover}; color: ${chart.toolbar.fontColorOnHover}</code>);
          });
          exportCSV.addEventListener('mouseout', () => {
            exportCSV.setAttribute('style', <code>padding: 12px 8px; background-color: ${chart.toolbar.itemBackgroundColor}; color: ${chart.toolbar.fontColor}</code>);
          });
          chart._toolBar.lastChild.appendChild(exportCSV);
        }
      }}
    />
  );
}

function App() {
  return <div className = "App"><Chart isLoading = {true} data = {[]} /></div>;
}

export default App;
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
0
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это непростая задача. Похоже, что библиотека изменяет DOM элементов панели инструментов каждый раз, когда она отображается. Я использую трюк, чтобы задержать рендеринг кнопки экспорта CSV на 2 секунды, чтобы дождаться стабилизации диаграммы.

https://stackblitz.com/edit/vitejs-vite-bpwzyk?file=src%2FApp.jsx,src%2FExportCSVButton.jsx

export default function ExportCSVButton({ chartRef }) {
  const divRef = useRef();

  useEffect(() => {
    const timer = setTimeout(() => {
      if (!divRef.current) return;
      divRef.current.innerText = 'Save As CSV';
    }, 2000);

    return () => clearTimeout(timer);
  });

  return (
    chartRef?._toolBar?.lastChild &&
    createPortal(
      <div
        ref = {divRef}
        style = {{
          padding: '12px 8px',
          backgroundColor: '#666666',
          color: '#F5F5F5',
        }}
      >
        Save As CSV
      </div>,
      chartRef?._toolBar?.lastChild
    )
  );
}

Обновлено: поэтому вместо задержки рендеринга портала я просто сбрасываю внутренний текст div каждый раз, когда компонент перерисовывается (из-за изменения родительского состояния).

спасибо, но если реквизиты изменятся, ошибка все равно будет выдаваться. stackblitz.com/edit/vitejs-vite-cz1oex?file=src%2FApp.jsx

ssss 03.04.2024 12:19

@ssss Эй, я обновил свой ответ и ссылку, можешь посмотреть еще раз?

quyentho 04.04.2024 21:01
Ответ принят как подходящий

Я сообщил об ошибке в Canvasjs, и они исправили проблему в новой версии.

Другие вопросы по теме