AppProvider
Description
A React context provider that manages global application state. The AppProvider wraps the entire application and provides access to the GraphQL response data, configuration, props map, widgets, and page fetching state. It handles client-side navigation and updates the context when navigating through the application.
Import
import { AppProvider } from '@components/common/context/app';
Usage
import { AppProvider } from '@components/common/context/app';
function App() {
const initialData = {
graphqlResponse: {},
config: {
pageMeta: { title: 'My Store' },
tax: { priceIncludingTax: false },
catalog: { imageDimensions: { width: 1200, height: 1200 } }
},
propsMap: {},
widgets: [],
fetching: false
};
return (
<AppProvider value={initialData}>
<YourAppComponents />
</AppProvider>
);
}
Props
| Name | Type | Description |
|---|---|---|
| value | AppStateContextValue | The initial application state containing GraphQL data, config, props, and widgets |
| children | React.ReactNode | Child components that need access to the app context |
AppStateContextValue Type
interface AppStateContextValue {
graphqlResponse: {
[key: string]: any;
};
config: Config;
propsMap: Record<string, any[]>;
widgets?: any[];
fetching: boolean;
}
interface Config {
pageMeta: PageMetaInfo;
tax: {
priceIncludingTax: boolean;
};
catalog: {
imageDimensions: { width: number; height: number };
};
}
Features
State Management
The provider manages two types of state:
- Application Data: GraphQL responses, configuration, props, and widgets
- Fetching State: Tracks when page data is being loaded
Client-Side Navigation
The provider automatically handles browser back/forward navigation:
- Listens to
popstateevents - Fetches updated page data via AJAX
- Updates context with new data using Immer for immutability
Context Dispatch Methods
Provides methods to update the application state:
setData: Directly set the entire application statefetchPageData: Fetch and update data from a URL
Example: Server-Side Rendering
import { AppProvider } from '@components/common/context/app';
export function ServerApp({ contextData }) {
return (
<AppProvider value={contextData}>
<Router>
<Layout>
<Routes />
</Layout>
</Router>
</AppProvider>
);
}
Example: Accessing Context
Use the hooks to access the app context in child components:
import { useAppState, useAppDispatch } from '@components/common/context/app';
function MyComponent() {
const { graphqlResponse, config, fetching } = useAppState();
const { fetchPageData } = useAppDispatch();
const loadNewPage = async () => {
const url = new URL('/new-page', window.location.origin);
url.searchParams.append('ajax', 'true');
await fetchPageData(url.toString());
};
if (fetching) {
return <div>Loading...</div>;
}
return (
<div>
<h1>{config.pageMeta.title}</h1>
<button onClick={loadNewPage}>Load New Page</button>
</div>
);
}
Related Hooks
- useAppState - Access the application state
- useAppDispatch - Access methods to update the state
Notes
- The provider uses Immer's
producefunction to ensure immutable state updates - When fetching page data, the URL is automatically appended with
ajax=trueparameter - The entire context is replaced when new data is fetched, not merged
- The
fetchingstate is managed separately from the main application data