diff --git a/.eslintrc.json b/.eslintrc.json index aa759e8..2869709 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,6 +23,7 @@ "react-hooks/exhaustive-deps": ["error", { "additionalHooks": "useIsomorphicLayoutEffect" }], "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-empty-interface": "off", "react/jsx-filename-extension": ["error", { "extensions": [".js", ".tsx"] }], "react/prop-types": "off", @@ -32,7 +33,7 @@ "import/no-unresolved": ["error", { "ignore": ["reactive-react-redux"] }], "no-param-reassign": "off", "no-plusplus": "off", - "prefer-object-spread": "off", + "no-bitwise": "off", "default-case": "off" }, "overrides": [{ diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..23feaa3 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,44 @@ +name: CD + +on: + push: + tags: + - v* + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Setup Node + uses: actions/setup-node@v1 + with: + node-version: '12.x' + registry-url: 'https://registry.npmjs.org' + + - name: Get yarn cache + id: yarn-cache + run: echo "::set-output name=dir::$(yarn cache dir)" + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install dependencies + run: yarn install + + - name: Test + run: yarn test + + - name: Compile + run: yarn run compile + + - name: Publish + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..eeb5e68 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI + +on: + push: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Setup Node + uses: actions/setup-node@v1 + with: + node-version: '12.x' + + - name: Get yarn cache + id: yarn-cache + run: echo "::set-output name=dir::$(yarn cache dir)" + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install dependencies + run: yarn install + + - name: Test + run: yarn test diff --git a/.gitignore b/.gitignore index b9d243e..66cc957 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *~ *.swp node_modules +/dist diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2bc4f39..0000000 --- a/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - 10 - - 12 diff --git a/README.md b/README.md index 8a8e5c4..9d05676 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # reactive-react-redux -[](https://travis-ci.com/dai-shi/reactive-react-redux) -[](https://badge.fury.io/js/reactive-react-redux) -[](https://bundlephobia.com/result?p=reactive-react-redux) +[](https://github.com/dai-shi/reactive-react-redux/actions?query=workflow%3ACI) +[](https://www.npmjs.com/package/reactive-react-redux) +[](https://bundlephobia.com/result?p=reactive-react-redux) React Redux binding with React Hooks and Proxy @@ -30,16 +30,19 @@ Most likely, `useTrackedState` performs better than Technically, `useTrackedState` has no [stale props](https://react-redux.js.org/api/hooks#stale-props-and-zombie-children) issue. -### 2. state-based object for context value +### 2. useMutableSource without Context -react-redux v7 uses store-based object for context value, -while react-redux v6 used to use state-based object. -Using state-based object naively has -[unable-to-bail-out issue](https://github.com/facebook/react/issues/14110), -but this library uses state-based object with -undocumented function `calculateChangedBits` -to stop propagation of re-renders. -See [#29](https://github.com/dai-shi/reactive-react-redux/issues/29) for details. +react-redux v7 has APIs around Context. +This library is implemented with useMutableSource, +and it patches the Redux store. +APIs are provided without Context. +It's up to developers to use Context based on them. +Check out `./examples/11_todolist/src/context.ts`. + +There's another difference from react-redux v7. +This library directly use useMutableSource, and requires +useCallback for the selector in useSelector. +[equalityFn](https://react-redux.js.org/api/hooks#equality-comparisons-and-updates) is not supported. ## How tracking works @@ -62,8 +65,7 @@ npm install reactive-react-redux import React from 'react'; import { createStore } from 'redux'; import { - Provider, - useDispatch, + patchStore, useTrackedState, } from 'reactive-react-redux'; @@ -81,11 +83,11 @@ const reducer = (state = initialState, action) => { } }; -const store = createStore(reducer); +const store = patchStore(createStore(reducer)); const Counter = () => { - const state = useTrackedState(); - const dispatch = useDispatch(); + const state = useTrackedState(store); + const { dispatch } = store; return (