增加WASM模块上下文。

This commit is contained in:
徐涛 2024-12-26 15:34:25 +08:00
parent db19e9354d
commit 63dd0cc686
3 changed files with 84 additions and 5 deletions

View File

@ -1,4 +1,5 @@
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import { ColorFunctionProvider } from './ColorFunctionContext';
import { Notifications } from './components/Notifications';
import { Home } from './pages/Home';
import { MainLayout } from './pages/MainLayout';
@ -28,9 +29,11 @@ const routes = createBrowserRouter([
export function App() {
return (
<Notifications>
<title>Color Lab</title>
<RouterProvider router={routes}></RouterProvider>
</Notifications>
<ColorFunctionProvider>
<Notifications>
<title>Color Lab</title>
<RouterProvider router={routes}></RouterProvider>
</Notifications>
</ColorFunctionProvider>
);
}

View File

@ -0,0 +1,56 @@
import {
createContext,
ReactNode,
useCallback,
useEffect,
useMemo,
useState,
useTransition,
} from 'react';
import type * as Wasm from './pkg/color_module';
import init from './pkg/color_module';
export const ColorFunctionContext = createContext<{
colorFn: Wasm.InitOutput | null;
isLoading: boolean;
error: Error | null;
}>({
colorFn: null,
isLoading: true,
error: null,
});
type WasmProviderProps = {
children?: ReactNode;
};
export function ColorFunctionProvider({ children }: WasmProviderProps) {
const [wasmInstance, setWasmInstance] = useState<Wasm.InitOutput | null>(null);
const [isPending, startTransition] = useTransition();
const [error, setError] = useState<Error | null>(null);
const loadWasm = useCallback(() => {
startTransition(async () => {
try {
const wasm = await init();
setWasmInstance(wasm);
} catch (e) {
console.error('[Load WASM]', e);
setError(e);
}
});
}, []);
const contextValue = useMemo(
() => ({
colorFn: wasmInstance,
isLoading: isPending,
error,
}),
[wasmInstance, isPending, error],
);
useEffect(() => {
loadWasm();
}, []);
return <ColorFunctionContext value={contextValue}>{children}</ColorFunctionContext>;
}

View File

@ -1,3 +1,23 @@
import { isNil } from 'lodash-es';
import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useScheme } from '../stores/schemes';
export function SchemeDetail() {
return <div></div>;
const { id } = useParams();
const scheme = useScheme(id);
const navigate = useNavigate();
useEffect(() => {
if (isNil(scheme)) {
navigate('../not-found');
}
}, [scheme, navigate]);
return (
<div>
<h3>{scheme?.name}</h3>
<p>{scheme?.description}</p>
</div>
);
}