mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 17:36:08 +08:00
ui-next: page data context
This commit is contained in:
5 files changed
+50
-4
No files matched your search
@@ -1,2 +1,4 @@
|
||||
export type { Context } from './src/context';
|
||||
export { usePageData } from './src/pageData';
|
||||
export type { PageData } from './src/pageData';
|
||||
export type { ComponentName } from './src/registry';
|
||||
@@ -69,7 +69,7 @@ export async function apply(ctx: Context) {
|
||||
},
|
||||
});
|
||||
const middleware = c2k(vite.middlewares);
|
||||
const capture = ['/@vite/', '/src/', '/node_modules/', '/@react-refresh', '/@fs'];
|
||||
const capture = ['/@vite/', '/src/', '/node_modules/', '/@react-refresh', '/@fs', '/@id/'];
|
||||
for (const route of capture) {
|
||||
ctx.server.addCaptureRoute(route, middleware);
|
||||
}
|
||||
@@ -78,7 +78,7 @@ export async function apply(ctx: Context) {
|
||||
name: 'next',
|
||||
accept: [],
|
||||
output: 'html',
|
||||
asFallback: false,
|
||||
asFallback: true,
|
||||
priority: 100,
|
||||
async render(name, args, context) {
|
||||
const data = {
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { usePageData } from './pageData';
|
||||
import { Component } from './registry';
|
||||
|
||||
const AppInner = Component('page:app', () => <div>app</div>);
|
||||
const AppInner = Component('page:app', () => {
|
||||
const { data } = usePageData();
|
||||
|
||||
return <div>app, page:{data.name}</div>;
|
||||
});
|
||||
|
||||
export default AppInner;
|
||||
@@ -3,14 +3,22 @@ import { createRoot } from 'react-dom/client';
|
||||
import plugins from 'virtual:hydro-plugins';
|
||||
import App from './App';
|
||||
import { createContext } from './context';
|
||||
import { type PageData, PageDataProvider } from './pageData';
|
||||
|
||||
const ctx = createContext();
|
||||
for (const plugin of plugins) {
|
||||
plugin.apply(ctx);
|
||||
}
|
||||
|
||||
const injectionEl = document.getElementById('__HYDRO_INJECTION__');
|
||||
const initialData: PageData = injectionEl
|
||||
? JSON.parse(injectionEl.textContent!)
|
||||
: { name: 'invalid_init', args: {}, url: window.location.pathname };
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
<PageDataProvider initial={initialData}>
|
||||
<App />
|
||||
</PageDataProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
@@ -0,0 +1,31 @@
|
||||
import { createContext, type ReactNode, useContext, useState } from 'react';
|
||||
|
||||
export interface PageData {
|
||||
name: string;
|
||||
args: Record<string, any>;
|
||||
url: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface PageDataContextValue {
|
||||
data: PageData;
|
||||
setData: (data: PageData) => void;
|
||||
}
|
||||
|
||||
const PageDataContext = createContext<PageDataContextValue | null>(null);
|
||||
|
||||
export function PageDataProvider({ initial, children }: { initial: PageData, children: ReactNode }) {
|
||||
const [data, setData] = useState<PageData>(initial);
|
||||
return (
|
||||
<PageDataContext.Provider value={{ data, setData }}>
|
||||
{children}
|
||||
</PageDataContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export function usePageData(): PageDataContextValue {
|
||||
const ctx = useContext(PageDataContext);
|
||||
if (!ctx) throw new Error('usePageData must be used within PageDataProvider');
|
||||
return ctx;
|
||||
}
|
||||
Reference in new issue
Block a user