Skip to content

Events

KlineCharts emits “actions” (zoom, scroll, crosshair move, clicks, …). react-klinecharts exposes them as typed React props and a useChartEvent hook.

Pass callbacks directly to <KLineChart>. Each is strongly typed — the argument matches the payload KlineCharts emits.

<KLineChart
data={data}
onZoom={({ scale }) => console.log("scale:", scale)}
onCrosshairChange={(crosshair) => console.log(crosshair?.kLineData?.close)}
onCandleBarClick={(bar) => console.log("clicked:", bar.close)}
onVisibleRangeChange={(range) => console.log(`${range.from}..${range.to}`)}
/>
Prop Payload Fires when
onReady (chart: Chart) Chart initialized (not an action).
onZoom { scale: number } Chart zoom.
onChartScroll { distance } Chart scroll (renamed to avoid clashing with the native DOM onScroll).
onVisibleRangeChange VisibleRange Visible data range changes.
onCrosshairChange Crosshair | null Crosshair moves / leaves.
onCandleBarClick KLineData A candle bar is clicked.
onPaneDrag { paneId: string } A pane is dragged.
onCandleTooltipFeatureClick unknown Candle tooltip feature clicked.
onIndicatorTooltipFeatureClick unknown Indicator tooltip feature clicked.
onCrosshairFeatureClick unknown Crosshair feature clicked.

For nested components, use useChartEvent. The callback is stored in a ref, so its identity can change every render without re-subscribing.

import { useChartEvent } from "react-klinecharts";
function Logger() {
useChartEvent("onCrosshairChange", (crosshair) => {
console.log("x:", crosshair?.x, "y:", crosshair?.y);
});
return null;
}

The callback argument is typed based on the action type — useChartEvent("onZoom", (data) => ...) gives you { scale: number }, not unknown.

The wrapper exports ActionPayloadMap and TypedActionCallback<T> so you can reuse the payload types in your own code:

import type { ActionPayloadMap, TypedActionCallback, ActionType } from "react-klinecharts";
type ZoomPayload = ActionPayloadMap["onZoom"]; // { scale: number }
const handler: TypedActionCallback<"onZoom"> = ({ scale }) => {};

Each subscription is wired through a stable wrapper that reads the latest callback from a ref. This avoids the classic React pitfall where an inline event handler captures stale state — you always get the freshest closure, and KlineCharts never sees a subscription churn.