From 9baf151cb76c528241532c4a1cea788b1e639783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DOUIN?= Date: Fri, 27 May 2022 09:21:26 +0200 Subject: [PATCH 1/4] add dispatch to the effect reducer --- CHANGELOG.md | 10 +++++++--- README.md | 2 +- src/index.spec.tsx | 2 +- src/index.ts | 14 ++++++++------ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 285dd67..3db53fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,23 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- The `EffectReducer` takes now a second argument dispatch `React.Dispatch`. + ## [1.0.5] - 2022-05-26 ### Fix -- Export only UMD and ESM formats +- Export only UMD and ESM formats. ## [1.0.4] - 2022-05-26 ### Fix -- Modern js export +- Fix modern js export. ## [1.0.3] - 2022-05-26 ### Fix -- Microbundle export names +- Fix Microbundle export names. ## [1.0.2] - 2022-05-26 diff --git a/README.md b/README.md index 85edc2d..923e806 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The effect reducer just executes effects and can return a cleanup function. This cleanup function is called when the component unmounts: ```typescript -type EffectReducer = (effect: E) => void | (() => void); +type EffectReducer = (effect: E, dispatch: React.Dispatch) => void | (() => void); ``` This pattern helps you to separate state changes from effectful diff --git a/src/index.spec.tsx b/src/index.spec.tsx index 111341b..b644498 100644 --- a/src/index.spec.tsx +++ b/src/index.spec.tsx @@ -41,7 +41,7 @@ const stateReducer: StateReducer = (state, action) => { } }; -const effectReducer: EffectReducer = effect => { +const effectReducer: EffectReducer = effect => { switch (effect.type) { case "log": { console.log(effect.value); diff --git a/src/index.ts b/src/index.ts index 7a5fb1a..dca5493 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,15 @@ -import {useCallback, useEffect, useReducer, useRef, useState} from "react"; +import {Dispatch, useCallback, useEffect, useReducer, useRef, useState} from "react"; export type StateReducer = (state: S, action: A) => [S, E[]]; -export type EffectReducer = (effect: E) => EffectCleanup | void; +export type EffectReducer = (effect: E, dispatch: Dispatch) => EffectCleanup | void; export type EffectCleanup = () => void; export function useBireducer( stateReducer: StateReducer, - effectReducer: EffectReducer, + effectReducer: EffectReducer, defaultState: S, -) { +): [S, Dispatch] { const [effects, setEffects] = useState([]); const cleanups = useRef([]); @@ -22,10 +22,12 @@ export function useBireducer( [stateReducer], ); + const [state, dispatch] = useReducer(reducer, defaultState); + useEffect(() => { const effect = effects.pop(); if (effect) { - const cleanup = effectReducer(effect); + const cleanup = effectReducer(effect, dispatch); if (cleanup) cleanups.current.push(cleanup); setEffects([...effects]); } @@ -39,7 +41,7 @@ export function useBireducer( }; }, []); - return useReducer(reducer, defaultState); + return [state, dispatch]; } export default {useBireducer}; From 1963463939bed4292d651cbbf2ce4d03583b8d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DOUIN?= Date: Fri, 27 May 2022 09:44:13 +0200 Subject: [PATCH 2/4] add similar projects section in readme --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 923e806..5d49185 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,14 @@ Library](https://testing-library.com/docs/react-testing-library/intro/) yarn test ``` +## Similar projects + +- [`useEffectReducer`](https://github.com/davidkpiano/useEffectReducer): + the state reducer exposes a third argument called `exec` to schedule + effects +- [`useElmish`](https://github.com/ncthbrt/react-use-elmish): it is a + mix between `useEffectReducer` and `useBireducer` + ## Sponsoring [![github](https://img.shields.io/badge/-GitHub%20Sponsors-fafbfc?logo=GitHub%20Sponsors&style=flat-square)](https://github.com/sponsors/soywod) From a17e1e1b399aaee14ede5a19e559e7a11776aaa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DOUIN?= Date: Fri, 27 May 2022 09:57:36 +0200 Subject: [PATCH 3/4] add dispatch test from effect reducer --- src/index.spec.tsx | 49 ++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/index.spec.tsx b/src/index.spec.tsx index b644498..0294799 100644 --- a/src/index.spec.tsx +++ b/src/index.spec.tsx @@ -8,30 +8,18 @@ type State = { count: number; }; -type Action = - | {type: "increment"; value: number} - | {type: "decrement"; value: number} - | {type: "reset"}; +type Action = {type: "update"; value: number} | {type: "reset"}; type Effect = {type: "log"; value: string} | {type: "backup"; count: number}; const stateReducer: StateReducer = (state, action) => { switch (action.type) { - case "increment": { - return [ - {count: state.count + action.value}, - [{type: "log", value: `increment counter +${action.value}`}], - ]; - } - case "decrement": { - return [ - {count: state.count - action.value}, - [{type: "log", value: `decrement counter -${action.value}`}], - ]; + case "update": { + return [{count: action.value}, [{type: "log", value: `set counter ${action.value}`}]]; } case "reset": { return [ - {count: 0}, + state, [ {type: "log", value: "reset counter"}, {type: "backup", count: state.count}, @@ -41,7 +29,7 @@ const stateReducer: StateReducer = (state, action) => { } }; -const effectReducer: EffectReducer = effect => { +const effectReducer: EffectReducer = (effect, dispatch) => { switch (effect.type) { case "log": { console.log(effect.value); @@ -49,6 +37,7 @@ const effectReducer: EffectReducer = effect => { } case "backup": { localStorage.setItem("backup", String(effect.count)); + dispatch({type: "update", value: 0}); return () => { localStorage.clear(); }; @@ -80,9 +69,21 @@ describe("useBireducer", () => { return ( <> {state.count} - + + ); } @@ -93,15 +94,17 @@ describe("useBireducer", () => { fireEvent.click(screen.getByTestId("increment")); fireEvent.click(screen.getByTestId("increment")); expect(screen.getByTestId("counter")).toHaveTextContent("2"); - expect(console.log).toHaveBeenNthCalledWith(2, "increment counter +1"); + expect(console.log).toHaveBeenNthCalledWith(1, "set counter 1"); + expect(console.log).toHaveBeenNthCalledWith(2, "set counter 2"); fireEvent.click(screen.getByTestId("decrement")); expect(screen.getByTestId("counter")).toHaveTextContent("1"); - expect(console.log).toHaveBeenLastCalledWith("decrement counter -1"); + expect(console.log).toHaveBeenNthCalledWith(3, "set counter 1"); fireEvent.click(screen.getByTestId("reset")); expect(screen.getByTestId("counter")).toHaveTextContent("0"); - expect(console.log).toHaveBeenLastCalledWith("reset counter"); + expect(console.log).toHaveBeenNthCalledWith(4, "reset counter"); + expect(console.log).toHaveBeenNthCalledWith(5, "set counter 0"); expect(localStorage.setItem).toHaveBeenNthCalledWith(1, "backup", "1"); expect(localStorage.clear).not.toHaveBeenCalled(); From 1ee710e78f887b4198bc2a0a8bfa264168cb1b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DOUIN?= Date: Fri, 27 May 2022 10:18:32 +0200 Subject: [PATCH 4/4] prepare v1.1.0 --- CHANGELOG.md | 12 ++++++++++-- package.json | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3db53fd..205d40e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.1.0] - 2022-05-27 + +### Added + +- Motivation and Similar projects section in readme. + ### Changed -- The `EffectReducer` takes now a second argument dispatch `React.Dispatch`. +- The `EffectReducer` takes now a second argument dispatch of type + `React.Dispatch`. ## [1.0.5] - 2022-05-26 @@ -35,7 +42,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.0.0] - 2022-05-26 -[unreleased]: https://github.com/soywod/react-use-bireducer/compare/v1.0.5...HEAD +[unreleased]: https://github.com/soywod/react-use-bireducer/compare/v1.1.0...HEAD +[1.1.0]: https://github.com/soywod/react-use-bireducer/compare/v1.0.5...v1.1.0 [1.0.5]: https://github.com/soywod/react-use-bireducer/compare/v1.0.4...v1.0.5 [1.0.4]: https://github.com/soywod/react-use-bireducer/compare/v1.0.3...v1.0.4 [1.0.3]: https://github.com/soywod/react-use-bireducer/compare/v1.0.2...v1.0.3 diff --git a/package.json b/package.json index c0f22e6..43ec033 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "react-use-bireducer", "author": "soywod ", "description": "React hook for managing effects from reducers.", - "version": "1.0.5", + "version": "1.1.0", "license": "MIT", "source": "src/index.ts", "typings": "dist/index.d.ts",