Last active
June 10, 2019 18:43
-
-
Save donut/4a62ac83887b140cd131c8c2bbdcdb6a to your computer and use it in GitHub Desktop.
A wrapper for React's useReducer() hook that applies middleware. Written in OCaml.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let use_reducer ?(middleware=[]) reducer initial = | |
(* [middlewared_dispatch] is setup as a reference so we can change it to the | |
dispatch function returned by [useReducer]. This way we can insert | |
middleware before the real reducer function runs. *) | |
let middlewared_dispatch = React.useRef (fun a -> | |
Js.Console.error2 "Dispatch called before reducer hook initialized." a) | |
in | |
let apply_middleware middleware state action = | |
let dispatch = React.Ref.current middlewared_dispatch in | |
let rec apply action = function | |
| [] -> action | |
| hd :: tl -> | |
match hd ~dispatch state action with | |
| `Rerun a -> apply a middleware | |
| `Next a -> apply a tl | |
| `Stop a -> a | |
in | |
apply action middleware | |
in | |
let middlewared_reducer state action = | |
action | |
|> apply_middleware middleware state | |
|> reducer state | |
in | |
let state, dispatch = React.useReducer middlewared_reducer initial in | |
React.Ref.setCurrent middlewared_dispatch dispatch; | |
(state, dispatch) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment