LoginSignup
72
38

More than 5 years have passed since last update.

【React Hooks】useReducer + useContextでグローバルなストアを扱う

Last updated at Posted at 2018-12-11

TL;DR

useReducer単体だと、グローバルなストアを扱う事が現状出来ないので
useContextと併用して、なるべくシンプルに、グローバルなストアを扱うreact-reduxライクなアーキテクチャを実現してみる

こんな感じ

store.js
import React, {useReducer} from 'react'
import reducer from './reducer'

const initialState = {
  count : 0
}

const Store = React.createContext()

const Provider = ({children}) => {
  const [state, dispatch] = useReducer(reducer, initialState)
  return <Store.Provider value={{state, dispatch}}>{children}</Store.Provider>
}

export { Store, Provider }
reducer.js
const reducer = (state = {}, action) => {
  switch(action.type) {
    case 'INCREMENT':
     return {
       ...state,
       count : count + 1
     }
    case 'DECREMENT':
     return {
       ...state,
       count : count - 1
     }
    default:
      return state
  }
}

export default reducer
index.js
import React, { useContext } from 'react'
import { render } from 'react-dom'

import { Provider, Store } from './store'

const Counter = () => {
  const {state, dispatch} = useContext(Store)  
  return (
   <>
    count : {state.count}
    <div>
     <button onClick={() => dispatch({ type : 'INCREMENT' })}>increment</button>
     <button onClick={() => dispatch({ type : 'DECREMENT' })}>decrement</button>
    </div>
   </>
  )
}

const App = () => (
  <Provider>
   <Counter />
  </Provider>
)

render(
  <App />,
  document.getElementById('root')
)

シンプル!

  • connect関数っぽい書き方ではないけど、ちゃんとコンポーネントとグローバルストアをconnectしてくれる
  • useContext(Store)が、自分が当初から欲していた幻のuseGlobal(もしくはuseStore)に当たる
    • 『コレだ!』感
  • redux-sagaの様な、hooksと非同期処理を良しなに取り持ってくれる、デファクトなミドルウェアは多分まだ固まりきっていないので、非同期なactionは割り切って書かない想定(な構成)

参考サイト (ていうかほぼ丸々引y(ry)

72
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
72
38