Skip to content

Commit

Permalink
fix: avoid unnecessary re-renders in basic cases
Browse files Browse the repository at this point in the history
Refs: #439
  • Loading branch information
targos committed Nov 1, 2022
1 parent 6b9db11 commit 34892fb
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 12 deletions.
6 changes: 4 additions & 2 deletions src/components/Axis/LinearAxis.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ScaleLinear } from 'd3-scale';
import { useRef } from 'react';
import { memo, useRef } from 'react';
import { useLinearPrimaryTicks } from 'react-d3-utils';

import HorizontalAxis from './HorizontalAxis';
Expand All @@ -10,7 +10,7 @@ interface LinearAxisProps extends AxisChildProps<number> {
scale: ScaleLinear<number, number>;
}

export default function LinearAxis(props: LinearAxisProps) {
function LinearAxis(props: LinearAxisProps) {
const { position, tickLabelFormat, scale, ...otherProps } = props;

const axisRef = useRef<SVGGElement>(null);
Expand All @@ -35,3 +35,5 @@ export default function LinearAxis(props: LinearAxisProps) {
/>
);
}

export default memo(LinearAxis);
6 changes: 4 additions & 2 deletions src/components/Axis/LogAxis.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ScaleLogarithmic } from 'd3-scale';
import { useRef } from 'react';
import { memo, useRef } from 'react';
import { useLogTicks } from 'react-d3-utils';

import HorizontalAxis from './HorizontalAxis';
Expand All @@ -10,7 +10,7 @@ interface LogAxisProps extends AxisChildProps<number> {
scale: ScaleLogarithmic<number, number>;
}

export default function LogAxis(props: LogAxisProps) {
function LogAxis(props: LogAxisProps) {
const { position, tickLabelFormat, scale, ...otherProps } = props;

const axisRef = useRef<SVGGElement>(null);
Expand All @@ -34,3 +34,5 @@ export default function LogAxis(props: LogAxisProps) {
/>
);
}

export default memo(LogAxis);
6 changes: 4 additions & 2 deletions src/components/Axis/TimeAxis.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ScaleTime } from 'd3-scale';
import { useRef } from 'react';
import { memo, useRef } from 'react';
import { useTimeTicks } from 'react-d3-utils';

import HorizontalAxis from './HorizontalAxis';
Expand All @@ -10,7 +10,7 @@ interface TimeAxisProps extends AxisChildProps<Date> {
scale: ScaleTime<number, number>;
}

export default function TimeAxis(props: TimeAxisProps) {
function TimeAxis(props: TimeAxisProps) {
const { position, tickLabelFormat, scale, ...otherProps } = props;

const axisRef = useRef<SVGGElement>(null);
Expand All @@ -35,3 +35,5 @@ export default function TimeAxis(props: TimeAxisProps) {
/>
);
}

export default memo(TimeAxis);
6 changes: 4 additions & 2 deletions src/components/Series/LineSeries.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { line } from 'd3-shape';
import { CSSProperties, useEffect, useMemo } from 'react';
import { CSSProperties, memo, useEffect, useMemo } from 'react';

import { useLegend } from '../../contexts/legendContext';
import { usePlotContext } from '../../contexts/plotContext';
Expand All @@ -19,7 +19,7 @@ export interface LineSeriesProps<T extends SeriesPoint = SeriesPoint>
lineStyle?: CSSFuncProps<{ id: string }>;
}

export function LineSeries<T extends SeriesPoint = SeriesPoint>(
function LineSeriesInner<T extends SeriesPoint = SeriesPoint>(
props: LineSeriesProps<T>,
) {
const [, legendDispatch] = useLegend();
Expand Down Expand Up @@ -104,6 +104,8 @@ export function LineSeries<T extends SeriesPoint = SeriesPoint>(
);
}

export const LineSeries = memo(LineSeriesInner);

interface LineSeriesRenderProps {
id: string;
data: ReadonlyArray<SeriesPoint>;
Expand Down
6 changes: 4 additions & 2 deletions src/components/Series/RangeSeries.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { extent } from 'd3-array';
import { area } from 'd3-shape';
import { CSSProperties, useEffect, useMemo } from 'react';
import { CSSProperties, memo, useEffect, useMemo } from 'react';

import { useLegend } from '../../contexts/legendContext';
import {
Expand All @@ -23,7 +23,7 @@ export interface RangeSeriesProps<T extends RangeSeriesPoint>
lineStyle?: CSSProperties;
}

export function RangeSeries<T extends RangeSeriesPoint>(
function RangeSeriesInner<T extends RangeSeriesPoint>(
props: RangeSeriesProps<T>,
) {
const id = useId(props.id, 'series');
Expand Down Expand Up @@ -103,6 +103,8 @@ export function RangeSeries<T extends RangeSeriesPoint>(
return isVisible ? <RangeSeriesRender {...lineProps} /> : null;
}

export const RangeSeries = memo(RangeSeriesInner);

interface RangeSeriesRenderProps {
data: ReadonlyArray<RangeSeriesPoint>;
xAxis: string;
Expand Down
12 changes: 10 additions & 2 deletions src/contexts/legendContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ReactNode,
Reducer,
useContext,
useMemo,
useReducer,
} from 'react';

Expand Down Expand Up @@ -37,7 +38,7 @@ type LegendActions =
| ActionType<'TOGGLE_VISIBILITY', { id: string }>;

type LegendDispatch = Dispatch<LegendActions>;
type LegendContext = [LegendState, LegendDispatch];
type LegendContext = readonly [LegendState, LegendDispatch];

const context = createContext<LegendContext | null>(null);

Expand Down Expand Up @@ -93,6 +94,13 @@ const initialLegendState: LegendState = {
};

export const LegendProvider = (props: { children: ReactNode }) => {
const ctx = useReducer(legendReducer, initialLegendState);
const [legendState, legendDispatch] = useReducer(
legendReducer,
initialLegendState,
);
const ctx = useMemo(
() => [legendState, legendDispatch] as const,
[legendState, legendDispatch],
);
return <context.Provider value={ctx}>{props.children}</context.Provider>;
};

0 comments on commit 34892fb

Please sign in to comment.