react-reducer-provider.github.io

Asynchronous/Synchronous React Centralized State

Follow me on GitHub

React Reducer Provider with Actions Creators

1 . Add react-reducer-provider (and prerequisite) to package.json:

  ..
  "dependencies": {
    "react": "^16.8.0"
    "react-reducer-provider": "5.0.0",
    ..

2 . Define the States, the Actions and the Reducer:

SomeReducer.js:

const initialState = 0

function reduce(prevState, action) {
  switch (action) {
    case 'ACTION1':
      return prevState + 1
    case 'ACTION2':
      return prevState - 1
    default:
      return prevState
  }
}

export {
  initialState,
  reduce
}

3 . Create the Reducer Provider:

SomeReducerProvider.jsx:

import { initialState, reduce } from '../path/to/SomeReducer'
import React from 'react'
import { SyncReducerProvider } from 'react-reducer-provider'

function SomeReducerProvider({ children }) {
  return (
    <SyncReducerProvider
      id='someNamedReducer'
      reducer={reduce}
      initialState={initialState}
    >
      {children}
    </SyncReducerProvider>
  )
}

export {
  someNamedReducer as default,
  SomeReducerProvider
}

4 . Define the Actions Creators through a custom React Hook, which will represent the bridge between the Reducer Provider and the Components:

SomeActions.js:

import { useReducer } from 'react-reducer-provider'
import React from 'react'

export default function useActions() {
  const [ state, dispatch ] = useReducer('someNamedReducer')
  return {
    state,
    actions: {
      goUp: () => {
        dispatch('ACTION1')
      },
      goDown: () => {
        dispatch('ACTION2')
      }
    }
  }
}

It may require the use of useMemo and useCallback to “improve” performance, check MockingReducerProvider.test.jsx.

5 . Define some Components:

SomeComponent1.jsx:

import React from 'react'

export default function SomeComponent1({onClick}) {
  return (
    <button onClick={onClick}>
      Go up!
    </button>
  )
}

SomeComponent2.jsx:

import React from 'react'

export default function SomeComponent2({onClick}) {
  return (
    <button onClick={onClick}>
      Go down!
    </button>
  )
}

SomeComponentN.jsx:

import React from 'react'

export default function SomeComponentN({currentState}) {
  return (
    <div>
      Current:{currentState}
    </div>
  )
}

6 . Use Actions Creators:

SomeContainer.jsx:

import SomeComponent1 from './path/to/SomeComponent1'
import SomeComponent2 from './path/to/SomeComponent2'
import SomeComponentN from './path/to/SomeComponentN'
import useActions from "./path/to/SomeActions"
import React from 'react'

export default function SomeContainer() {
  const {state, actions} = useActions();
  return (
    <div>
      <SomeComponent1 onClick={actions.goUp} />
      <SomeComponent2 onClick={actions.goDown} />
      <SomeComponentN currentState={state}/>
    </div>
  )
}

SomeMain.jsx:

import SomeContainer from './path/to/SomeContainer'
import { SomeReducerProvider } from '../path/to/SomeReducerProvider'
import React from 'react'

export default function SomeContainer() {
  return (
    <SomeReducerProvider>
      <SomeContainer />
    </SomeReducerProvider>
  )
}

This example can be checked on line at gmullerb-react-reducer-provider-with-actions-creators codesandbox:
Edit gmullerb-react-reducer-provider-with-actions-creators
with Flow typings.
with Typescript typings.

Main documentation

Back to homepage