diff --git a/apps/playground/src/hooks/react-signal.ts b/apps/playground/src/hooks/react-signal.ts index 85c0e8f..d2dbb94 100644 --- a/apps/playground/src/hooks/react-signal.ts +++ b/apps/playground/src/hooks/react-signal.ts @@ -13,7 +13,6 @@ import {useCallback, useEffect, useReducer, useRef, useSyncExternalStore} from ' * Use `Signal` inside React component. * ___ * ⚠️ [Experimental] Lack of testing. **DO NOT** use in production. - * - `useSignal`'s setter causes component to re-render twice on strict mode. */ export function useSignal(): SignalFactoryReturnType; export function useSignal(value: T, options?: SignalOptions): SignalFactoryReturnType; @@ -26,17 +25,17 @@ export function useSignal( signalRef.current = createSignal(value, {equals, onChange}); } - useSyncExternalStore( - useCallback((onStoreChange) => { - const cleanupEffect = createEffect(() => { + const externalSubscribe = useCallback[0]>( + (onStoreChange) => + createEffect(() => { signalRef.current?.[0](); onStoreChange(); - }); - return cleanupEffect; - }, []), - signalRef.current[0], + }), + [], ); + useSyncExternalStore(externalSubscribe, signalRef.current[0]); + return signalRef.current; } @@ -56,7 +55,7 @@ export const useSignalEffect = (effect: SignalEffect) => { useEffect(() => { const cleanupEffect = createEffect(effect); // forceUpdate(); - return () => cleanupEffect(); + return cleanupEffect; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); }; diff --git a/apps/playground/src/routeTree.gen.ts b/apps/playground/src/routeTree.gen.ts index 74dd3f6..fc37522 100644 --- a/apps/playground/src/routeTree.gen.ts +++ b/apps/playground/src/routeTree.gen.ts @@ -16,11 +16,17 @@ import { Route as rootRoute } from './routes/__root' // Create Virtual Routes +const OtherLazyImport = createFileRoute('/other')() const SignalRouteLazyImport = createFileRoute('/signal')() const IndexRouteLazyImport = createFileRoute('/')() // Create/Update Routes +const OtherLazyRoute = OtherLazyImport.update({ + path: '/other', + getParentRoute: () => rootRoute, +} as any).lazy(() => import('./routes/other.lazy').then((d) => d.Route)) + const SignalRouteLazyRoute = SignalRouteLazyImport.update({ path: '/signal', getParentRoute: () => rootRoute, @@ -49,6 +55,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof SignalRouteLazyImport parentRoute: typeof rootRoute } + '/other': { + id: '/other' + path: '/other' + fullPath: '/other' + preLoaderRoute: typeof OtherLazyImport + parentRoute: typeof rootRoute + } } } @@ -57,6 +70,7 @@ declare module '@tanstack/react-router' { export const routeTree = rootRoute.addChildren({ IndexRouteLazyRoute, SignalRouteLazyRoute, + OtherLazyRoute, }) /* prettier-ignore-end */ @@ -68,7 +82,8 @@ export const routeTree = rootRoute.addChildren({ "filePath": "__root.tsx", "children": [ "/", - "/signal" + "/signal", + "/other" ] }, "/": { @@ -76,6 +91,9 @@ export const routeTree = rootRoute.addChildren({ }, "/signal": { "filePath": "signal/route.lazy.tsx" + }, + "/other": { + "filePath": "other.lazy.tsx" } } } diff --git a/apps/playground/src/routes/other.lazy.tsx b/apps/playground/src/routes/other.lazy.tsx new file mode 100644 index 0000000..b30af26 --- /dev/null +++ b/apps/playground/src/routes/other.lazy.tsx @@ -0,0 +1,5 @@ +import {createLazyFileRoute} from '@tanstack/react-router'; + +export const Route = createLazyFileRoute('/other')({ + component: () =>
Hello /other!
, +}); diff --git a/apps/playground/src/routes/signal/route.lazy.tsx b/apps/playground/src/routes/signal/route.lazy.tsx index b1df483..2d17022 100644 --- a/apps/playground/src/routes/signal/route.lazy.tsx +++ b/apps/playground/src/routes/signal/route.lazy.tsx @@ -1,4 +1,4 @@ -import {createLazyFileRoute} from '@tanstack/react-router'; +import {createLazyFileRoute, Link} from '@tanstack/react-router'; import {playgroundSignal} from './-utils/store'; import PlaygroundChild3 from './-components/PlaygroundChild3'; import {useState} from 'react'; @@ -111,10 +111,13 @@ function PlaygroundChild2() { function SignalPlayground() { return ( -
- - - -
+ <> + Other page +
+ + + +
+ ); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a9b024..6eadd30 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ importers: apps/playground: dependencies: + '@kaiverse/k': + specifier: ^0.1.0 + version: 0.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@kaiverse/signal': specifier: workspace:* version: link:../../packages/signal @@ -450,6 +453,12 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@kaiverse/k@0.1.0': + resolution: {integrity: sha512-E+oqBjF1V7s/oh/TCi4ryxKc7DoXXqhp+/k9ol7XBgf/kBjVg8snVFAniAFWO15UoNGzK50zrzMr7VpDzeckIg==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + '@manypkg/find-root@1.1.0': resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} @@ -2519,6 +2528,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@kaiverse/k@0.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + '@manypkg/find-root@1.1.0': dependencies: '@babel/runtime': 7.25.4