OskaDev

OskaDev

React Context API & Usage

simple showcase about react-context and how i using it

Long time ago React already have Context API but doens't have react hooks at that time we may need another state management library such as Redux, Mobx. But for now it's React Hooks introduced, and I would been using this in production environment without any state management library. Just because why take the thing to complicated when it can be simple?, here i will show how i using it and why i using it.

In react, we able to maintain local component state using useState() and lifecycle using useEffect() and we will using useContext() to get our context in any child component. So we start with create our own context, in context we will using class, you can also use function instead class depend yourself which one preferred. Usually context we will using it for side actions such as api call, native functionality ( notification, firebase ) and some controller for global component ( dialog, loader ). Here an example context class and how we using it in view.

import { createContext } from "react";
import AuthAPI from "./auth";

class RootAPI {

    constructor() {
        this.auth = new AuthAPI(this);
        this.loader = {
            show: () => { throw Error("rootapi: loader isn't intiialized") },
            hide: () => { throw Error("rootapi: loader isn't intiialized") }
        }
    }

}

const RootContext = createContext(new RootAPI());
export { RootAPI }
export default RootContext;

// AuthAPI ( you can move another page, just make it easier to show )
class AuthAPI {

    constructor(root) {
        this.root = root;
        this.login = false;
    }

}

export default AuthAPI;
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

reportWebVitals();


// app.js
import RootAPI, { RootContext } from "./api";
import Home from "./views/home";


function App() {
    const root = new RootAPI();

    return (
        <RootContext.Provider value={root}>
            <Home />
        </RootContext.Provider>
    )
}

export default App;

// views/home.js
import { useContext, useEffect, useState } from "react";
import RootContext from "../api";

function Home() {
    const root = useContext(RootContext);
    const [auth, setAuth] = useState(root.auth.login)

    useEffect(() => {
        root.auth.login = auth
    }, [auth]);

    return (
        <div>
            <input
                type="submit"
                onClick={() => setAuth(!auth)}
            />
        </div>
    )
}

export default Home;

Why i using this is because IntelliSense and a cleaner structure for me. From my view, every view should have their own state, if we're trying to use shared state we should define it and other developer who will continue this project will saw what shared state is used in this view and what local state is defined also it have intellisense. For me intellisense will increase a lot of productivity and development speed because i'm no need to keep look back what property or function at object. Some global view and component will have a controller for other children components to use, so for intellisense i will define a simple no-op object for the controller then we will know what function controller have.

This structure design i already using it in React and React Native, and both perform well for me. If you have any suggestion or enhancement for this design, i like to know more about this. You can contact me in any of my social links. I have similar design in Flutter will release at next time when i'm free, also been using it in production one of my colleague is like it very much.

References:

  1. reactjs.org
  2. github.com/Oskang09/react-context-sample
  3. noop.com.au/noop-meaning
  4. reactjs.org/docs/context.html
  5. reactjs.org/docs/hooks-intro.html
 
Share this