Replace onLayout with ref to measure Canvas size#605
Replace onLayout with ref to measure Canvas size#605zibs merged 6 commits intoFormidableLabs:mainfrom
Conversation
🦋 Changeset detectedLatest commit: 831e652 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
Ooh, this is interesting, thanks for following up here @TomCorvus -- will take a look at this. |
There was a problem hiding this comment.
Pull Request Overview
This PR updates the code to work with react-native-skia version 2.2.x by replacing the deprecated onLayout prop on Canvas components with a ref-based approach for measuring Canvas size.
- Replace
onLayoutprop withuseCanvasRefhook andrefon Canvas components - Update
onLayoutcallback signature to accept width/height directly instead of LayoutChangeEvent - Upgrade react-native-skia dependency from 2.0.2 to 2.2.2
Reviewed Changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| package.json | Adds packageManager field specification |
| lib/src/polar/PolarChart.tsx | Replaces Canvas onLayout with ref-based measurement using useLayoutEffect |
| lib/src/cartesian/CartesianChart.tsx | Replaces Canvas onLayout with ref-based measurement using useLayoutEffect |
| example/package.json | Upgrades react-native-skia dependency to version 2.2.2 |
|
What do you think about an approach like this @TomCorvus? I'm trying to find a way that doesn't require anyone to be on a specific version of The example seems to be okay with this, but let me know what you think! diff --git a/lib/src/cartesian/CartesianChart.tsx b/lib/src/cartesian/CartesianChart.tsx
index 063797f..3d209af 100644
--- a/lib/src/cartesian/CartesianChart.tsx
+++ b/lib/src/cartesian/CartesianChart.tsx
@@ -649,7 +649,7 @@ function CartesianChartContent<
// Body of the chart.
const body = (
- <Canvas style={{ flex: 1 }} onLayout={onLayout}>
+ <Canvas style={{ flex: 1 }}>
{YAxisComponents}
{XAxisComponents}
{FrameComponent}
@@ -689,7 +689,10 @@ function CartesianChartContent<
}
return (
- <GestureHandlerRootView style={{ flex: 1, overflow: "hidden" }}>
+ <GestureHandlerRootView
+ style={{ flex: 1, overflow: "hidden" }}
+ onLayout={onLayout}
+ >
{body}
<GestureHandler
config={gestureHandlerConfig}
diff --git a/lib/src/polar/PolarChart.tsx b/lib/src/polar/PolarChart.tsx
index e9327c0..f11a7db 100644
--- a/lib/src/polar/PolarChart.tsx
+++ b/lib/src/polar/PolarChart.tsx
@@ -33,7 +33,7 @@ type PolarChartBaseProps = {
};
const PolarChartBase = (
- props: React.PropsWithChildren<PolarChartBaseProps>,
+ props: React.PropsWithChildren<PolarChartBaseProps>
) => {
const {
containerStyle,
@@ -52,15 +52,14 @@ const PolarChartBase = (
composed = Gesture.Race(
composed,
pinchTransformGesture(transformState),
- panTransformGesture(transformState),
+ panTransformGesture(transformState)
);
}
return (
- <View style={[styles.baseContainer, containerStyle]}>
+ <View onLayout={onLayout} style={[styles.baseContainer, containerStyle]}>
<GestureHandlerRootView style={{ flex: 1, overflow: "hidden" }}>
<Canvas
- onLayout={onLayout}
style={StyleSheet.flatten([
styles.canvasContainer,
hasMeasuredLayoutSize ? { width, height } : null,
@@ -84,7 +83,7 @@ type PolarChartProps<
RawData extends Record<string, unknown>,
LabelKey extends StringKeyOf<InputFields<RawData>>,
ValueKey extends StringKeyOf<NumericalFields<RawData>>,
- ColorKey extends StringKeyOf<ColorFields<RawData>>,
+ ColorKey extends StringKeyOf<ColorFields<RawData>>
> = {
data: RawData[];
colorKey: ColorKey;
@@ -98,11 +97,11 @@ export const PolarChart = <
RawData extends Record<string, unknown>,
LabelKey extends StringKeyOf<InputFields<RawData>>,
ValueKey extends StringKeyOf<NumericalFields<RawData>>,
- ColorKey extends StringKeyOf<ColorFields<RawData>>,
+ ColorKey extends StringKeyOf<ColorFields<RawData>>
>(
props: React.PropsWithChildren<
PolarChartProps<RawData, LabelKey, ValueKey, ColorKey>
- >,
+ >
) => {
const { data, labelKey, colorKey, valueKey } = props;
@@ -116,8 +115,9 @@ export const PolarChart = <
setHasMeasuredLayoutSize(true);
setCanvasSize(layout);
},
- [],
+ []
);
return (
<FiberProvider> |
…ific React Native Skia version
|
@zibs This approach works better for me — it completely avoids locking to a specific Skia version. |
zibs
left a comment
There was a problem hiding this comment.
Thank you very much @TomCorvus - great catch.
Description
Since
react-native-skia@2.2.x, theonLayoutprop is no longer available on theCanvascomponent. We now retrieve the size using arefon the Canvas.Fixes: #604
Type of Change
Note: Users must upgrade
react-native-skiato version2.2.2or later.How Has This Been Tested?
I verified that both Polar and Cartesian charts render at the correct size.
To minimize changes, the size is now retrieved using a Canvas
ref, and theonLayoutlogic is preserved inside auseLayoutEffect, as recommended by the RN Skia team:https://shopify.github.io/react-native-skia/docs/canvas/overview#canvas-size
Checklist
yarn run check:codeand all checks passNotes
Some ESLint warnings may appear regarding
useLayoutEffectdependencies (ref,onLayout).Since both values are stable, these warnings can be safely ignored using
// eslint-disable-next-line react-hooks/exhaustive-deps.