React Hook Store Context

It is a Simple Hook Store Context for react project using hooks

  1. counterReducer: Create a Reducer

  2. createStore: Create a Store

  3. StoreContext: Default StoreContext

  4. useSelector: Selecion a state from MAIN-STATE

  5. useDispatch: Reference a global dispatch of Store

Create a Reducer

Create a counterReducer.

export const counterReducer = (state, action) => {
    switch (action.type) {
        case '++':
            return { counter: state.counter + 1 };
        case '--':
            return { counter: state.counter - 1 };
        default:
            return state;
    }
}

Create a Store

Create a new Store, use useStore for declarin all reducers.

import { createStore } from 'react-hsc';
import { counterReducer } from './counterReducer';

export const basicStore = createStore({
    C1: [counterReducer, { counter: 0 }],
    // other reducers
    // NAME: [ fnReducer, initialState, fnInicializer]
});

Default StoreContext

Use the StoreContext and pass de basicStore.

import React from 'react'
import StoreContext from 'react-hsc';

import { basicStore } from './basicStore';
import { CounterDisplay } from './CounterDisplay';
import { CounterButtons } from './CounterButtons';
import { CounterActions } from './CounterActions';

export const BasicApp = () => {
    return (
        <StoreContext.Provider value={basicStore}>
            <CounterDisplay />
            <CounterButtons />
            <CounterActions />
        </StoreContext.Provider>
    )
}
export default BasicApp;

useSelector

useSelector for selection state from MAIN-STATE.

import React from 'react'
import { useSelector } from 'react-hsc';

export const CounterDisplay = () => {
    let { counter } = useSelector(state => state.C1);
    return (
        <h3>Counter: {counter}</h3>
    )
}

useDispatch

useDispatch for dispatch an action.

import React from 'react'
import { useDispatch } from 'react-hsc';

export const CounterButtons = () => {
    const dispatch = useDispatch();
    const onClick = (type) => {
        const action = { type }
        dispatch(action)
    }
    return (
        <div>
            <button onClick={e => onClick("++")}>+1</button>
            <button onClick={e => onClick("--")}>-1</button>
        </div>
    )
}

Actions supports

useDispatch for dispatch an action support string, function and async function parameters.

import React from 'react'
import { useDispatch } from 'react-hsc';

export const CounterActions = () => {
    const dispatch = useDispatch();
    const onClickAsString = (type) => {
        console.log('string action');
        // convert string to {type: string}
        dispatch(type)
    }
    const onClickAsFunction = (type) => {
        const fnAction = () => {
            console.log('function action');
            // return: {type, payload}
            return { type }
        }
        dispatch(fnAction)
    }
    const onClickAsAsyncFunction = (type) => {
        dispatch(fnAsyncAction)
    }
    return (
        <div>
            <button onClick={e => onClickAsString("++")}>+1 as String</button>
            <button onClick={e => onClickAsFunction("++")}>+1 as Function</button>
            <button onClick={e => onClickAsAsyncFunction("++")}>+1 as Async Function</button>
        </div>
    )
}
async function fnAsyncAction(dispatchAsync)  {
    console.log('----dispatchAsync', dispatchAsync);
    setTimeout(
        () => {
            console.log('async function action');
            // param: {type, payload}
            dispatchAsync({ type: '++' });
        },
        3000
    );
}

Custom Store Context

import React, { createContext } from 'react'
import { useSelector, useDispatch } from 'react-hsc';

import { basicStore } from './basicStore';

const CustomStore = createContext();

export const BasicApp = () => {
    return (
        <CustomStore.Provider value={basicStore}>
            <CounterDisplay />
            <CounterButtons />
        </CustomStore.Provider>
    )
}

export const CounterDisplay = () => {
    let { counter } = useSelector(state => state.C1, CustomStore);
    return (
        <h3>Counter: {counter}</h3>
    )
}

export const CounterButtons = () => {
    const dispatch = useDispatch(CustomStore);
    const onClick = (type) => {
        const action = { type }
        dispatch(action)
    }
    return (
        <div>
            <button onClick={e => onClick("++")}>+1</button>
            <button onClick={e => onClick("--")}>-1</button>
        </div>
    )
}
Note

This lib use the redux-plugin-devtools for show the MAIN-STATE context