Skip to content

Instantly share code, notes, and snippets.

@eldh
Last active April 1, 2019 15:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eldh/0351f4965beb2d5f0cc0cece65629551 to your computer and use it in GitHub Desktop.
Save eldh/0351f4965beb2d5f0cc0cece65629551 to your computer and use it in GitHub Desktop.
ReasonReact useReducer hook
type update('state, 'action) =
| NoUpdate
| Update('state)
| SideEffects(self('state, 'action) => unit)
| UpdateWithSideEffects('state, self('state, 'action) => unit)
and self('state, 'action) = {
state: 'state,
send: 'action => unit,
};
let useReducer = (reducer, initialState) => {
let extendedReducer = ((state, _), action) => {
(
switch (reducer(state, action)) {
| NoUpdate => state
| SideEffects(_) => state
| Update(s) => s
| UpdateWithSideEffects(s, _) => s
},
switch (reducer(state, action)) {
| SideEffects(f) => Some(f)
| UpdateWithSideEffects(_, f) => Some(f)
| Update(_)
| NoUpdate => None
},
);
};
let ((state, update), sendState) =
React.useReducer(extendedReducer, (initialState, None));
let _ =
React.useLayoutEffect1(
() => {
switch (update) {
| Some(u) => u({state, send: sendState})
| None => ()
};
None;
},
[|update|],
);
(state, sendState);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment