Data handling
Store chart data
For organizing your data, you should follow React principles as a foundation.
You should store dynamic data that changes over time in state, and keep static configuration as constants or inline within your components:
import React, { useState } from "react";import { Chart, Title, PlotOptions } from "@highcharts/react";import { LineSeries } from "@highcharts/react/series/Line";export default function MyChart() {const [series, setSeries] = useState({data: [1, 2, 3, 4, 5],options: {color: "green",},});return (<Chart><Title>My Chart</Title><PlotOptionsseries={{dataLabels: {enabled: true,format: "{y}",},}}/><LineSeries data={series.data} options={series.options} /></Chart>);}
Note: What qualifies as dynamic data depends on your use case. Store configuration in state if it needs to change over time. Otherwise, use constants.
Update chart data
To update your chart, you should modify the React state:
// Pattern: state → props → rerenderimport React, { useRef, useState } from "react";import { Chart, Title } from "@highcharts/react";import { LineSeries } from "@highcharts/react/series/Line";export default function MyChart() {const [title, setTitle] = useState("Initial title");const [points, setPoints] = useState([1, 2, 3, 4, 5]);const chartRef = useRef(null);const updateTitle = () => {setTitle("Updated title");// Avoid direct chart updates.// chartRef.current.chart.setTitle({ text: 'Updated title' });};const updatePoints = () => {setPoints([5, 4, 3, 2, 1]);// Avoid direct chart updates.// chartRef.current.chart.series[0].setData([5, 4, 3, 2, 1]);};return (<><Chart ref={chartRef}><Title>{title}</Title><LineSeries data={points} /></Chart><button onClick={updateTitle}>Change title</button><button onClick={updatePoints}>Shift data</button></>);}
Live demos:
Note: Direct chart updates are not recommended as they bypass React's state management, causing inconsistencies between your state and the displayed chart.
Add series dynamically
Because Series components are regular React components, you can create them from
state or props. This makes it straightforward to add new series at runtime:
import React from "react";import { Chart, Series, Subtitle, Title } from "@highcharts/react";const seriesCatalog = [{ id: "line", name: "Line", type: "line", data: [5, 7, 6, 8, 9] },{ id: "area", name: "Area", type: "area", data: [3, 4, 3, 5, 6] },{ id: "column", name: "Column", type: "column", data: [2, 3, 4, 3, 5] },];export default function ChartComponent() {const [activeSeriesIds, setActiveSeriesIds] = React.useState(() => [seriesCatalog[0].id,]);const toggleSeries = React.useCallback((seriesId) => {setActiveSeriesIds((current) => {if (current.includes(seriesId)) {return current.filter((id) => id !== seriesId);}return [...current, seriesId];});}, []);const activeSeries = React.useMemo(() => seriesCatalog.filter((series) => activeSeriesIds.includes(series.id)),[activeSeriesIds],);return (<div className="dynamic-basics-demo"><Chart>{/* ... chart options ... */}{activeSeries.map((series) => (<Serieskey={series.id}type={series.type}data={series.data}options={{...series.options,id: series.id,name: series.name,}}/>))}</Chart><SeriesControlsactiveSeriesIds={activeSeriesIds}onToggleSeries={toggleSeries}/></div>);}
This basic example uses the generic Series component for built-in chart types. For a more advanced
pattern that wires up Stock indicators dynamically, see the dedicated
dynamic React indicators sample.
Data mutation
By default, Highcharts treats your data as immutable and keeps state read-only. Increased performance with large datasets can be achieved by allowing Highcharts to mutate the data:
import React, { useState } from "react";import { Chart } from "@highcharts/react";import { LineSeries } from "@highcharts/react/series/Line";export default function MyChart() {const [data, setData] = useState([1, 2, 3, 4, 5]);return (<Chartoptions={{chart: {allowMutatingData: true,},}}><LineSeries data={data} /></Chart>);}
External State Management (Redux)
For large-scale applications, you may prefer to manage your data in an external store like Redux. Because @highcharts/react components are reactive by design, they synchronize seamlessly with global state via hooks like useSelector.
When an action is dispatched to the Redux store, the component re-renders with new props, and the chart performs an optimized update automatically.
import React from 'react';import { useSelector, useDispatch } from 'react-redux';import { Chart, Series, Title } from '@highcharts/react';import { randomizeData } from './store';export default function ReduxChart() {// Connect chart data to the global Redux stateconst points = useSelector((state) => state.chart.points);const dispatch = useDispatch();return (<div className="redux-chart-container"><Chart><Title>Redux-Powered Chart</Title><Series type="column" data={points} name="Global State Data" /></Chart><button onClick={() => dispatch(randomizeData())}>Randomize Global State</button></div>);}
Why use Redux with Highcharts React?
Centralized Logic: Keep data fetching and transformation logic (like calculating averages or normalizing time series) in your Reducers/Thunks.
Predictable Reactivity: Highcharts handles the complex DOM and SVG updates, while Redux handles the data integrity.
Performance: By mapping only the necessary slices of state to your chart components, you ensure the chart only re-renders when its specific data changes.