global-context
v1.1.1
Published
Global context for React
Downloads
5
Readme
Global Context for React
A single global context to act as a container for whatever you want
Install
yarn add global-context
Use
Imagine this structure:
/src
theme-engine.ts
state.ts
toolbar.tsx
app.tsx
Describe your dependency
import { BehaviorSubject } from 'rxjs'
import { AxiosInstance } from 'axios'
import * as CSS from 'csstype';
export class ThemeEngine {
theme = new BehaviorSubject<CSS.Properties>({
color: 'white',
backgroundColor: 'blue'
})
constructor(
private http: AxiosInstance
) {}
merge(styles: CSS.Properties) {
this.theme.next({
...this.theme.getValue(),
...styles,
})
}
replace(styles: CSS.Properties) {
this.theme.next(styles)
}
async fetch() {
const result = await this.http.get('https://theme-api.com')
this.merge(result.data)
}
}
Export your state object with it's loaded instances
// state.ts
import { ThemeEngine } from './theme-engine';
import axios, { AxiosInstance } from 'axios'
export const httpClient = axios.create()
export const themeEngine = new ThemeEngine(httpClient)
export interface State {
httpClient?: AxiosInstance
themeEngine?: ThemeEngine
}
export const state: State = {
httpClient,
themeEngine
}
Create your App and supply provider
// app.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { GlobalProvider } from 'global-context';
import { state } from './state'
import { Toolbar } from './toolbar'
const App = () => {
return (
<main>
<Toolbar>Welcome to my app</Toolbar>
</main>
)}
ReactDOM.render(
<GlobalProvider value={state}>
<App/>
</GlobalProvider>,
element
)
Consume a dependency using the hooks
// toolbar.tsx
import React from 'react';
import { useBehaviorSubject } from 'use-subscribable'
import { ThemeEngine } from './theme-engine';
import { useGlobalSelector } from 'global-context';
interface ToolbarProps {
children?: React.ReactNode
}
export const Toolbar = ({ children }: ToolbarProps) => {
const themeEngine = useGlobalSelector(ctx => ctx.themeEngine)
const themes = useBehaviorSubject(themeEngine.theme)
return (
<div style={{
color: themes.color,
backgroundColor: themes.backgroundColor
}}>
{ children }
</div>
)}