Skip to content

Instantly share code, notes, and snippets.

@broerjuang
Created April 17, 2020 17:22
Show Gist options
  • Save broerjuang/04596aed907e9decebb409d76994e88a to your computer and use it in GitHub Desktop.
Save broerjuang/04596aed907e9decebb409d76994e88a to your computer and use it in GitHub Desktop.
Renata
module AsyncResult = Relude.AsyncResult;
module Effect = ReludeReact.Effect;
module IO = Relude.IO;
module Option = Relude.Option;
module Reducer = ReludeReact.Reducer;
let (toBusy, completeOk, completeError) =
AsyncResult.(toBusy, completeOk, completeError);
type state('a, 'e) = AsyncResult.t('a, 'e);
type action('a, 'e, 't) =
| Mutate('t)
| MutateSucceed('a)
| MutateFailed('e);
type config('a, 'e, 't) = {
onSuccess: option('a => unit),
onError: option('e => unit),
handler: 't => IO.t('a, 'e),
};
let%private void = ();
let reducer = (config, state, action) => {
switch (action) {
| Mutate(t) =>
Reducer.UpdateWithIO(
state |> toBusy,
config.handler(t)
|> IO.bimap(d => MutateSucceed(d), e => MutateFailed(e)),
)
| MutateSucceed(d) =>
UpdateWithSideEffect(
d |> completeOk,
_self => {config.onSuccess |> Option.fold(void, fn => fn(d))},
)
| MutateFailed(e) =>
UpdateWithSideEffect(
e |> completeError,
_self => {config.onError |> Option.fold(void, fn => fn(e))},
)
};
};
let useMutation = (~onSuccess=?, ~onError=?, handler) => {
let (state, send) =
Reducer.useReducer(reducer({onSuccess, handler, onError}), Init);
(state, t => send(Mutate(t)));
};
@mfakhrusy
Copy link

thanks 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment