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.
Manual Context Injection
tsx
importReact from "react";import {Canvas ,Fill } from "@shopify/react-native-skia";import {useTheme ,ThemeProvider } from "./docs/getting-started/Theme";constMyDrawing = () => {const {primary } =useTheme ();return <Fill color ={primary } />;};export constLayer = () => {consttheme =useTheme ();return (<Canvas style ={{flex : 1 }}>{/* We need to re-inject the context provider here. */}<ThemeProvider primary ={theme .primary }><MyDrawing /></ThemeProvider ></Canvas >);};export constApp = () => {return (<ThemeProvider primary ="red"><Layer /></ThemeProvider >);};
tsx
importReact from "react";import {Canvas ,Fill } from "@shopify/react-native-skia";import {useTheme ,ThemeProvider } from "./docs/getting-started/Theme";constMyDrawing = () => {const {primary } =useTheme ();return <Fill color ={primary } />;};export constLayer = () => {consttheme =useTheme ();return (<Canvas style ={{flex : 1 }}>{/* We need to re-inject the context provider here. */}<ThemeProvider primary ={theme .primary }><MyDrawing /></ThemeProvider ></Canvas >);};export constApp = () => {return (<ThemeProvider primary ="red"><Layer /></ThemeProvider >);};
Using its-fine
tsx
importReact 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";constMyDrawing = () => {const {primary } =useTheme ();return <Fill color ={primary } />;};export constLayer = () => {constContextBridge =useContextBridge ();return (<Canvas style ={{flex : 1 }}><ContextBridge ><Fill color ="black" /><MyDrawing /></ContextBridge ></Canvas >);};export constApp = () => {return (<FiberProvider ><ThemeProvider primary ="red"><Layer /></ThemeProvider ></FiberProvider >);};
tsx
importReact 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";constMyDrawing = () => {const {primary } =useTheme ();return <Fill color ={primary } />;};export constLayer = () => {constContextBridge =useContextBridge ();return (<Canvas style ={{flex : 1 }}><ContextBridge ><Fill color ="black" /><MyDrawing /></ContextBridge ></Canvas >);};export constApp = () => {return (<FiberProvider ><ThemeProvider primary ="red"><Layer /></ThemeProvider ></FiberProvider >);};
Below is the context definition that was used in this example:
tsx
import type {ReactNode } from "react";importReact , {useContext ,createContext } from "react";interfaceTheme {primary : string;}export constThemeContext =createContext <Theme | null>(null);export constThemeProvider = ({primary ,children ,}: {primary : string;children :ReactNode ;}) => (<ThemeContext .Provider value ={{primary }}>{children }</ThemeContext .Provider >);export constuseTheme = () => {consttheme =useContext (ThemeContext );if (theme === null) {throw newError ("Theme provider not found");}returntheme ;};
tsx
import type {ReactNode } from "react";importReact , {useContext ,createContext } from "react";interfaceTheme {primary : string;}export constThemeContext =createContext <Theme | null>(null);export constThemeProvider = ({primary ,children ,}: {primary : string;children :ReactNode ;}) => (<ThemeContext .Provider value ={{primary }}>{children }</ThemeContext .Provider >);export constuseTheme = () => {consttheme =useContext (ThemeContext );if (theme === null) {throw newError ("Theme provider not found");}returntheme ;};