@mediatouch

Как вызвать функцию React компонента из вне?

Есть компонент Сhart (для создания графика chart.js):

import React, { useState, useEffect, useRef } from 'react';
import ChartJs from 'chart.js';

const chartConfig = {
	type: 'bar',
	data: {
		labels: [],
		datasets: [{
			label: '',
			data: [],
			backgroundColor: [],
			borderColor: [],
			borderWidth: 0,
			barPercentage: 1.0
		}]
	},
	options: {
		responsive: true,
		maintainAspectRatio: true,
		spanGaps: false,
		legend: {
			display: false
		},
		plugins: {
			filler: {
				propagate: false
			}
		},
		tooltips: {
			enabled: true
		},
		scales: {
			xAxes: [{
				gridLines: {
					display: false,
					offsetGridLines: true
				}
			}],
			yAxes: [{
				gridLines: {
					color: 'rgba(242, 243, 244, 1.0)',
					zeroLineWidth: 0
				},
				ticks: {
					beginAtZero: true
				}
			}]
		}
	}
};

const Chart = (props) => {
	const chartContainer = useRef(null);
	const [chartInstance, setChartInstance] = useState(null);

	const updateDataset = (datasetIndex, newLabels, newData) => {
		chartInstance.data.labels = props.labels;
		chartInstance.data.datasets[datasetIndex].data = props.data;
		chartInstance.update();
	};

	useEffect(() => {
		if (chartContainer && chartContainer.current) {
			const newChartInstance = new ChartJs(chartContainer.current, chartConfig);

			setChartInstance(newChartInstance);
		}
	}, [chartContainer]);

	return (
		<React.Fragment>
			<canvas ref={chartContainer} />
		</React.Fragment>
	);
};

export default Chart;


Далее я импортирую его уже в рабочем компоненте:
import Chart from '../../components/Chart';

И в теле компонента (jsx верстка) вставляю так:
<Chart />

Вопрос, как теперь в рабочем компоненте, где я вставил <Chart /> вызвать его функцию (и передать ей: datasetIndex, newLabels, newData) обновления данных - updateDataset?
  • Вопрос задан
  • 1052 просмотра
Решения вопроса 1
@dimoff66
Кратко о себе: Я есть
1) Как работает updateDataset ? Что она меняет, если она не меняет состояние? Она вызывает свойства chartInstance, но я не вижу, где этот объект у вас используется?

2) Логика React такова что все сообщение от родителя к детям идет исключительно через props-ы, поэтому по хорошему если вы что-то хотите поменять в дочернем элементе, вы должны изменить state родителя так, чтобы в дочерний элемент передались нужные пропсы, которые обрабатывались бы в дочернем элементе. Например в родительском рисуете элемент так

<Chart updateData={ [datasetIndex, newLabels, newData] }/>


а в Chart обрабатываете

if (props.updateData) updateDataset(...props.updateData)


Такой подход будет соответствовать принципам реакт.

3) Если все же хотите сделать по своему, то просто передайте в Chart функцию установки значения

let updateDataHandler = {}
return <Chart updateDataHandler={ h => { updateDataHandler = h } }/>


а внутри Chart напишите
props.updateDataHandler(updateDataset)

теперь в родительском компоненте updateDataHandler будет ссылаться на функцию Chart И вы можете ее спокойно вызывать
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Robur
@Robur
Знаю больше чем это необходимо
То что вы хотите сделать, правильно делать не так - нужно передавать данные через props,
дальше в useEffect брать эти пропсы и обновлять chartInstance.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы