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)