跳到主要内容

上下文

React Native Skia 使用其自己的 React 渲染器。目前无法在两个渲染器之间自动共享 React 上下文。这意味着 React Native 上下文不会直接在您的绘图中可用。我们建议在 <Canvas> 元素之外准备绘图所需的数据。但是,如果您需要在绘图中使用 React 上下文,则必须重新注入它。

我们找到了 its-fine,也被 react-three-fiber 使用,为这个问题提供了一个优雅的解决方案。

使用 its-fine

tsx
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>
);
};
tsx
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>
);
};

以下是此示例中使用的上下文定义

tsx
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;
};
tsx
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;
};