Skip to main content

Contexts

React Native Skia is using its own React renderer. It is currently impossible to automatically share a React context between two renderers. This means that a React Native context won't be available from your drawing directly. We recommend preparing the data needed for your drawing outside the <Canvas> element. However, if you need to use a React context within your drawing, you must re-inject it.

We found its-fine, also used by react-three-fiber, to provide an elegant solution to this problem.

Using its-fine

import React from "react";
import { Canvas, Fill } from "@shopify/react-native-skia";
import {useTheme, ThemeProvider, ThemeContext} from "./docs/getting-started/Theme";
import { useContextBridge, FiberProvider } from "its-fine";

const MyDrawing = () => {
const { primary } = useTheme();
return <Fill color={primary} />;
};

export const Layer = () => {
const ContextBridge = useContextBridge();
return (
<Canvas style={{ flex: 1 }}>
<ContextBridge>
<Fill color="black" />
<MyDrawing />
</ContextBridge>
</Canvas>
);
};

export const App = () => {
return (
<FiberProvider>
<ThemeProvider primary="red">
<Layer />
</ThemeProvider>
</FiberProvider>
);
};

Below is the context definition that was used in this example:

import type { ReactNode } from "react";
import React, { useContext, createContext } from "react";

interface Theme {
primary: string;
}

export const ThemeContext = createContext<Theme | null>(null);

export const ThemeProvider = ({
primary,
children,
}: {
primary: string;
children: ReactNode;
}) => (
<ThemeContext.Provider value={{ primary }}>
{children}
</ThemeContext.Provider>
);

export const useTheme = () => {
const theme = useContext(ThemeContext);
if (theme === null) {
throw new Error("Theme provider not found");
}
return theme;
};