1.1.1 • Published 5 years ago

global-context v1.1.1

Weekly downloads
13
License
MIT
Repository
-
Last release
5 years ago

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>
  )}
1.1.1

5 years ago

1.1.0

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago