react-reducer-provider
    TypeScript icon, indicating that this package has built-in type declarations

    5.1.0 • Public • Published

    Asynchronous/Synchronous React Centralized State

    with Hooks and HOC

    through Centralized Reducers/Mappers/Actuators

    Flux/Redux made Easy, Simple and Beyond

    react-reducer-provider react-reducer-provider      License   Github repo Gitlab repo


    react-reducer-provider provides a centralized state, managed asynchronously or synchronously through a reducer, mapper or actuator.


    Quick Start

    1 . Add dependency:

    package.json:

    when using hooks:

      ..
      "dependencies": {
        "react": ">=16.8.0"
        "react-reducer-provider": "5.1.0",
        ..

    when using HOC:

      ..
      "dependencies": {
        "react": ">=16.0.0"
        "react-reducer-provider": "5.1.0",
        ..

    Reducers

    2 . Create the AsyncReducerProvider or SyncReducerProvider component to manage the centralized state:

    Reducers

    a . Define the initial state.
    b . Define the reducer function.
    c . Define the Reducer Provider.

    SomeReducerProvider.jsx:

    import React from 'react'
    import { SyncReducerProvider } from 'react-reducer-provider'
    
    const initialState = 0
    
    function reduce(prevState, action, delta) {
      switch (action) {
        case 'ACTION1':
          return prevState + delta
        case 'ACTION2':
          return prevState - delta
        default:
          return prevState
      }
    }
    
    function SomeReducerProvider({ children }) {
      return (
        <SyncReducerProvider
          reducer={reduce}
          initialState={initialState}
        >
          {children}
        </SyncReducerProvider>
      )
    }
    
    export default SomeReducerProvider

    3 . Access the state and the dispatcher of the Provider component using the hooks or HOC provided by 'react-reducer-provider':

    Dispatcher

    SomeComponent1.jsx => using useReducer:

    import { useReducer } from 'react-reducer-provider'
    import React from 'react'
    
    export default function SomeComponent1() {
      const { state, dispatch } = useReducer()
      return (
        <button onClick={() => dispatch('ACTION1', 2)}>
          Go up (from {state})!
        </button>
      )
    }

    SomeComponent2.jsx => using injectReducerDispatcher:

    import { injectReducerDispatcher } from "react-reducer-provider";
    import React from "react";
    
    class SomeComponent2 extends React.Component {
      render() {
        return (
          <button onClick={() => {
            const newState = dispatch('ACTION2', 1)
            console.info(newState)
          }}>
            Go down!
          </button>
        )
      }
    }
    
    export default injectReducerDispatcher(SomeComponent2, 'dispatch')

    SomeComponentN.jsx => using useReducerState:

    import { useReducerState } from 'react-reducer-provider'
    import React from 'react'
    
    export default function SomeComponentN() {
      const currentState = useReducerState()
      return (
        <div>
          Current:{currentState}
        </div>
      )
    }

    4 . Wrap components which will consume the SomeReducerProvider component:

    SomeContainer.jsx:

    import SomeComponent1 from './path/to/SomeComponent1'
    import SomeComponent2 from './path/to/SomeComponent2'
    import SomeComponentN from './path/to/SomeComponentN'
    import SomeReducerProvider from '../path/to/SomeReducerProvider'
    import React from 'react'
    
    export default function SomeContainer() {
      return (
        <SomeReducerProvider>
          <SomeComponent1/>
          <SomeComponent2/>
          <SomeComponentN/>
        </SomeReducerProvider>
      )
    }

    SomeContainer

    This SyncReducerProvider example can be checked on line at gmullerb-react-reducer-provider codesandbox: Edit gmullerb-react-reducer-provider
    This SyncReducerProviderwith HOC example can be checked on line at gmullerb-react-reducer-provider codesandbox:
    Edit gmullerb-react-reducer-provider
    An AsyncReducerProvider example can be checked on line at gmullerb-react-reducer-provider-async codesandbox:
    Edit gmullerb-react-reducer-provider-async
    Examples of use can be looked at basecode-react-ts and test files.

    Mappers

    2 . Create the AsyncMapperProvider or SyncMapperProvider component to manage the centralized state:

    Mappers

    a . Define the initial state.
    b . Define the mapper function.
    c . Define the Mapper Provider.

    SomeMapperProvider.jsx:

    import React from "react";
    import { SyncMapperProvider } from "react-reducer-provider";
    
    const initialState = 0;
    
    function map(action) {
      switch (action) {
        case "ACTION1":
          return 1;
        case "ACTION2":
          return -1;
        default:
          return 0;
      }
    }
    
    function SomeMapperProvider({ children }) {
      return (
        <SyncMapperProvider
          id="someNamedMapper"
          mapper={map}
          initialState={initialState}
        >
          {children}
        </SyncMapperProvider>
      );
    }
    
    export { SomeMapperProvider };

    3 . Access the state and the dispatcher of the Provider component using the hooks or HOC provided by 'react-reducer-provider':

    Dispatcher

    SomeComponent1.jsx => using useMapper:

    import { useMapper } from "react-reducer-provider";
    import React from "react";
    
    export default function SomeComponent1() {
      const [state, dispatch] = useMapper("someNamedMapper");
      return (
        <button onClick={() => dispatch("ACTION1")}>
          Set to 1 (from {state})!
        </button>
      );
    }

    SomeComponent2.jsx => using useMapperDispatcher:

    import { useMapperDispatcher } from "react-reducer-provider";
    import React from "react";
    
    export default function SomeComponent2() {
      const dispatch = useMapperDispatcher("someNamedMapper");
      return <button onClick={() => dispatch("ACTION2")}>Set to -1!</button>;
    }

    SomeComponentN.jsx => using injectMapperState:

    import { injectMapperState } from "react-reducer-provider";
    import React from "react";
    
    class SomeComponentN extends React.Component {
      render() {
        return <div>Current:{this.props.currentState}</div>;
      }
    }
    
    export default injectMapperState(SomeComponentN, 'currentState')

    4 . Wrap components which will consume the SomeMapperProvider component:

    SomeContainer.jsx:

    import SomeComponent1 from "./SomeComponent1";
    import SomeComponent2 from "./SomeComponent2";
    import SomeComponentN from "./SomeComponentN";
    import { SomeMapperProvider } from "./SomeMapperProvider";
    import React from "react";
    
    export default function SomeContainer() {
      return (
        <SomeMapperProvider>
          <SomeComponent1 />
          <SomeComponent2 />
          <SomeComponentN />
        </SomeMapperProvider>
      );
    }

    SomeContainer

    An SyncMapperProvider example can be checked on line at gmullerb-react-mapper-provider codesandbox:
    Edit gmullerb-react-mapper-provider
    An AsyncMapperProvider example can be checked on line at gmullerb-react-mapper-provider-async codesandbox:
    Edit gmullerb-react-mapper-provider-async
    Examples of use can be looked at test files.

    Actuators

    2 . Create the ActuatorProvider component to manage a state (or whatever you need, not only state):

    Actuators

    a . Define actuator function.
    b . Define Actuator Provider.
    c. Wrap components which will consume the ActuatorProvider:

    SomeContainer.jsx:

    import SomeComponent1 from './path/to/SomeComponent1'
    import SomeComponent2 from './path/to/SomeComponent2'
    import { ActuatorProvider } from 'react-reducer-provider'
    import React from 'react'
    
    export function SomeContainer() {
      const [state, setState] = React.useState(0)
      const actuate = delta => setState(state + delta)
      return (
            <div>
              <ActuatorProvider actuator={actuate}>
                <SomeComponent1/>
                <SomeComponent2/>
              </ActuatorProvider>
              Current:{state}
            </div>
      )
    }

    3 . Access dispatcher of the Provider component using the hooks or HOC provided by 'react-reducer-provider':

    Dispatcher

    SomeComponent1.jsx => using useActuator:

    import { useActuator } from 'react-reducer-provider'
    import React from 'react'
    
    export function SomeComponent1() {
      const dispatch = useActuator()
      return (
        <button onClick={() => dispatch(+1)}>
          Go up!
        </button>
      )
    }

    SomeComponent2.jsx => using injectActuator:

    import { injectActuator } from "react-reducer-provider";
    import React from "react";
    
    class SomeComponent2 extends React.Component {
      render() {
        return (
          <button
            onClick={() => {
              const newState = this.props.dispatch(-1);
              console.info(newState);
            }}
          >
            Go down!
          </button>
        );
      }
    }
    
    export default injectActuator(SomeComponent2, "dispatch");

    SomeContainer

    This ActuatorProvider example can be checked on line at gmullerb-react-actuator-provider codesandbox: Edit gmullerb-react-reducer-provider
    Examples of use can be looked at test files.


    Goal

    With the introduction of React Hooks, in some way using Flux library[1] was deprecated, react-reducer-provider looks to give a quick and easy alternative using hooks to implement Flux with reducers.

    [1] Not the Flux architecture.
    [2] react-redux makes it too complicated.
    [3] Check and Compare with other solutions at bundlephobia.com.
    react-reducer-provider is the evolution of react-named-reducer (which is a derivation of react-reducer-context).


    You define:

    Reducers

    or

    Mappers

    or

    Actuators


    and then you use them through a:

    Dispatcher


    Prerequisites

    At least ["react": ">=16.0.0"] - React Context => when using HOC, i.e. injectReducer · injectReducerState · injectReducerDispatcher · injectMapper · injectMapperState · injectMapperDispatcher or injectTaggedAny · injectTaggedReducer · injectTaggedReducerState · injectTaggedReducerDispatcher · injectTaggedMapper · injectTaggedMapperState · injectTaggedMapperDispatcher.

    ["react": ">=16.8.0"] - React Hooks => when using hooks, i.e. useReducer · useReducerState · useReducerDispatcher · useMapper · useMapperState · useMapperDispatcher or useTaggedAny · useTaggedReducer · useTaggedReducerState · useTaggedReducerDispatcher · useTaggedMapper · useTaggedMapperState · useTaggedMapperDispatcher.

    react-reducer-provider only enforces "react": ">=16.0.0" in package.json is up to you to be set which version you need.


    Documentation

    Contributing

    License

    MIT License


    Remember

    • Use code style verification tools => Encourages Best Practices, Efficiency, Readability and Learnability.
    • Code Review everything => Encourages Functional suitability, Performance Efficiency and Teamwork.
    • If viable, Start testing early => Encourages Reliability and Maintainability.

    Additional words

    Don't forget:

    • Love what you do.
    • Learn everyday.
    • Learn yourself.
    • Share your knowledge.
    • Think different!.
    • Learn from the past, dream on the future, live and enjoy the present to the max!.
    • Enjoy and Value the Quest (It's where you learn and grow).

    At life:

    • Let's act, not complain.
    • Be flexible.

    At work:

    • Let's give solutions, not questions.
    • Aim to simplicity not intellectualism.

    Install

    npm i react-reducer-provider

    DownloadsWeekly Downloads

    7

    Version

    5.1.0

    License

    MIT

    Unpacked Size

    93.1 kB

    Total Files

    37

    Last publish

    Collaborators

    • gmullerb