use-context-selector
Advanced tools
Comparing version 0.4.0 to 1.0.0
@@ -5,2 +5,6 @@ # Change Log | ||
## [1.0.0] - 2019-08-02 | ||
### Changed | ||
- Fix API v1 | ||
## [0.4.0] - 2019-07-23 | ||
@@ -7,0 +11,0 @@ ### Changed |
@@ -1,2 +0,2 @@ | ||
import e from"react";var r=function(e){return e+1},t=Symbol("C_L"),n=function(r){var n,u,c=e.createContext(r,function(){return 0});return c[t]=new Set,c.Provider=(n=c.Provider,u=c[t],e.memo(function(r){var t=r.value,c=r.children;return u.forEach(function(e){e(t)}),e.createElement(n,{value:t},c)})),delete c.Consumer,c},u=function(n,u){var c=n[t];if(!c)throw new Error("useContextSelector requires special context");var o=e.useReducer(r,0)[1],f=e.useContext(n),i=u(f),a=e.useRef(null);return e.useLayoutEffect(function(){a.current={f:u,v:f,s:i}}),e.useLayoutEffect(function(){var e=function(e){try{if(a.current.v===e||Object.is(a.current.s,a.current.f(e)))return}catch(e){}o()};return c.add(e),function(){c.delete(e)}},[o,c]),i},c=function(e){return u(e,function(e){return e})};export{n as createContext,c as useContext,u as useContextSelector}; | ||
import e from"react";var r=function(e){return e+1},t=Symbol("C_L"),n=function(r){var n,u,c=e.createContext(r,function(){return 0});return c[t]=new Set,c.Provider=(n=c.Provider,u=c[t],e.memo(function(r){var t=r.value,c=r.children;return u.forEach(function(e){e(t)}),e.createElement(n,{value:t},c)})),delete c.Consumer,c},u=function(n,u){var c=n[t];if(!c)throw new Error("useContextSelector requires special context");var o=e.useReducer(r,0)[1],f=e.useContext(n),i=u(f),a=e.useRef(null);return e.useLayoutEffect(function(){a.current={f:u,v:f,s:i}}),e.useLayoutEffect(function(){var e=function(e){try{if(a.current.v===e||Object.is(a.current.s,a.current.f(e)))return}catch(e){}o()};return c.add(e),function(){c.delete(e)}},[c]),i},c=function(e){return u(e,function(e){return e})};export{n as createContext,c as useContext,u as useContextSelector}; | ||
//# sourceMappingURL=index.esm.js.map |
@@ -1,2 +0,2 @@ | ||
var e,t=(e=require("react"))&&"object"==typeof e&&"default"in e?e.default:e,r=function(e){return e+1},n=Symbol("C_L"),u=function(e,u){var o=e[n];if(!o)throw new Error("useContextSelector requires special context");var c=t.useReducer(r,0)[1],f=t.useContext(e),i=u(f),a=t.useRef(null);return t.useLayoutEffect(function(){a.current={f:u,v:f,s:i}}),t.useLayoutEffect(function(){var e=function(e){try{if(a.current.v===e||Object.is(a.current.s,a.current.f(e)))return}catch(e){}c()};return o.add(e),function(){o.delete(e)}},[c,o]),i};exports.createContext=function(e){var r,u,o=t.createContext(e,function(){return 0});return o[n]=new Set,o.Provider=(r=o.Provider,u=o[n],t.memo(function(e){var n=e.value,o=e.children;return u.forEach(function(e){e(n)}),t.createElement(r,{value:n},o)})),delete o.Consumer,o},exports.useContext=function(e){return u(e,function(e){return e})},exports.useContextSelector=u; | ||
var e,t=(e=require("react"))&&"object"==typeof e&&"default"in e?e.default:e,r=function(e){return e+1},n=Symbol("C_L"),u=function(e,u){var o=e[n];if(!o)throw new Error("useContextSelector requires special context");var c=t.useReducer(r,0)[1],f=t.useContext(e),i=u(f),a=t.useRef(null);return t.useLayoutEffect(function(){a.current={f:u,v:f,s:i}}),t.useLayoutEffect(function(){var e=function(e){try{if(a.current.v===e||Object.is(a.current.s,a.current.f(e)))return}catch(e){}c()};return o.add(e),function(){o.delete(e)}},[o]),i};exports.createContext=function(e){var r,u,o=t.createContext(e,function(){return 0});return o[n]=new Set,o.Provider=(r=o.Provider,u=o[n],t.memo(function(e){var n=e.value,o=e.children;return u.forEach(function(e){e(n)}),t.createElement(r,{value:n},o)})),delete o.Consumer,o},exports.useContext=function(e){return u(e,function(e){return e})},exports.useContextSelector=u; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e=e||self).useContextSelector={},e.react)}(this,function(e,t){t=t&&t.hasOwnProperty("default")?t.default:t;var n=function(e){return e+1},r=Symbol("C_L"),u=function(e,u){var o=e[r];if(!o)throw new Error("useContextSelector requires special context");var c=t.useReducer(n,0)[1],f=t.useContext(e),i=u(f),a=t.useRef(null);return t.useLayoutEffect(function(){a.current={f:u,v:f,s:i}}),t.useLayoutEffect(function(){var e=function(e){try{if(a.current.v===e||Object.is(a.current.s,a.current.f(e)))return}catch(e){}c()};return o.add(e),function(){o.delete(e)}},[c,o]),i};e.createContext=function(e){var n,u,o=t.createContext(e,function(){return 0});return o[r]=new Set,o.Provider=(n=o.Provider,u=o[r],t.memo(function(e){var r=e.value,o=e.children;return u.forEach(function(e){e(r)}),t.createElement(n,{value:r},o)})),delete o.Consumer,o},e.useContext=function(e){return u(e,function(e){return e})},e.useContextSelector=u}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e=e||self).useContextSelector={},e.react)}(this,function(e,t){t=t&&t.hasOwnProperty("default")?t.default:t;var n=function(e){return e+1},r=Symbol("C_L"),u=function(e,u){var o=e[r];if(!o)throw new Error("useContextSelector requires special context");var c=t.useReducer(n,0)[1],f=t.useContext(e),i=u(f),a=t.useRef(null);return t.useLayoutEffect(function(){a.current={f:u,v:f,s:i}}),t.useLayoutEffect(function(){var e=function(e){try{if(a.current.v===e||Object.is(a.current.s,a.current.f(e)))return}catch(e){}c()};return o.add(e),function(){o.delete(e)}},[o]),i};e.createContext=function(e){var n,u,o=t.createContext(e,function(){return 0});return o[r]=new Set,o.Provider=(n=o.Provider,u=o[r],t.memo(function(e){var r=e.value,o=e.children;return u.forEach(function(e){e(r)}),t.createElement(n,{value:r},o)})),delete o.Consumer,o},e.useContext=function(e){return u(e,function(e){return e})},e.useContextSelector=u}); | ||
//# sourceMappingURL=index.umd.js.map |
{ | ||
"name": "use-context-selector", | ||
"description": "React useContextSelector hook in userland", | ||
"version": "0.4.0", | ||
"version": "1.0.0", | ||
"author": "Daishi Kato", | ||
@@ -25,2 +25,3 @@ "repository": { | ||
"tsc-test": "tsc --project . --noEmit", | ||
"apidoc": "documentation build --format md --markdown-toc false src/index.js | add-text-to-markdown README.md --section API --write", | ||
"examples:minimal": "DIR=01_minimal EXT=js webpack-dev-server", | ||
@@ -41,10 +42,12 @@ "examples:typescript": "DIR=02_typescript webpack-dev-server" | ||
"@babel/preset-react": "^7.0.0", | ||
"@testing-library/react": "^8.0.5", | ||
"@types/react": "^16.8.23", | ||
"@types/react-dom": "^16.8.4", | ||
"@testing-library/react": "^8.0.7", | ||
"@types/react": "^16.8.24", | ||
"@types/react-dom": "^16.8.5", | ||
"@typescript-eslint/eslint-plugin": "^1.13.0", | ||
"@typescript-eslint/parser": "^1.13.0", | ||
"add-text-to-markdown": "^2.0.0", | ||
"babel-core": "^7.0.0-bridge.0", | ||
"babel-eslint": "^10.0.2", | ||
"babel-loader": "^8.0.6", | ||
"documentation": "^12.1.1", | ||
"eslint": "^6.1.0", | ||
@@ -63,3 +66,3 @@ "eslint-config-airbnb": "^17.1.1", | ||
"typescript": "^3.5.3", | ||
"webpack": "^4.36.1", | ||
"webpack": "^4.39.1", | ||
"webpack-cli": "^3.3.6", | ||
@@ -69,3 +72,3 @@ "webpack-dev-server": "^3.7.2" | ||
"peerDependencies": { | ||
"react": ">=16.8.6" | ||
"react": ">=16.8.0" | ||
}, | ||
@@ -72,0 +75,0 @@ "babel": { |
@@ -93,2 +93,60 @@ # use-context-selector | ||
## API | ||
<!-- Generated by documentation.js. Update this documentation by updating the source code. --> | ||
### createContext | ||
This create a special context for `useContextSelector`. | ||
#### Parameters | ||
- `defaultValue` **any** | ||
#### Examples | ||
```javascript | ||
const PersonContext = createContext({ firstName: '', familyName: '' }); | ||
``` | ||
Returns **React.Context** | ||
### useContextSelector | ||
This hook returns context selected value by selector. | ||
It will only accept context created by `createContext`. | ||
It will trigger re-render if only the selected value is referencially changed. | ||
#### Parameters | ||
- `context` **React.Context** | ||
- `selector` **[Function][1]** | ||
#### Examples | ||
```javascript | ||
const firstName = useContextSelector(PersonContext, state => state.firstName); | ||
``` | ||
Returns **any** | ||
### useContext | ||
This hook returns the entire context value. | ||
Use this instead of React.useContext for consistent behavior. | ||
#### Parameters | ||
- `context` **React.Context** | ||
#### Examples | ||
```javascript | ||
const person = useContext(PersonContext); | ||
``` | ||
Returns **any** | ||
[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function | ||
## Limitations | ||
@@ -99,3 +157,3 @@ | ||
- Context consumers are not supported. | ||
- The "stale props" issue can't be solved in userland. (workaround with try-catch) | ||
- The [stale props](https://react-redux.js.org/api/hooks#stale-props-and-zombie-children) issue can't be solved in userland. (workaround with try-catch) | ||
@@ -102,0 +160,0 @@ ## Examples |
@@ -18,4 +18,9 @@ import React from 'react'; | ||
// createContext | ||
/** | ||
* This create a special context for `useContextSelector`. | ||
* @param {*} defaultValue | ||
* @returns {React.Context} | ||
* @example | ||
* const PersonContext = createContext({ firstName: '', familyName: '' }); | ||
*/ | ||
export const createContext = (defaultValue) => { | ||
@@ -33,4 +38,12 @@ // make changedBits always zero | ||
// useContextSelector | ||
/** | ||
* This hook returns context selected value by selector. | ||
* It will only accept context created by `createContext`. | ||
* It will trigger re-render if only the selected value is referencially changed. | ||
* @param {React.Context} context | ||
* @param {Function} selector | ||
* @returns {*} | ||
* @example | ||
* const firstName = useContextSelector(PersonContext, state => state.firstName); | ||
*/ | ||
export const useContextSelector = (context, selector) => { | ||
@@ -41,3 +54,3 @@ const listeners = context[CONTEXT_LISTENERS]; | ||
} | ||
const forceUpdate = React.useReducer(forcedReducer, 0)[1]; | ||
const [, forceUpdate] = React.useReducer(forcedReducer, 0); | ||
const value = React.useContext(context); | ||
@@ -69,11 +82,16 @@ const selected = selector(value); | ||
}; | ||
}, [forceUpdate, listeners]); | ||
}, [listeners]); | ||
return selected; | ||
}; | ||
// useContext | ||
// use this instead of React.useContext for consistent behavior. | ||
// this is not best implemented in performance, | ||
/** | ||
* This hook returns the entire context value. | ||
* Use this instead of React.useContext for consistent behavior. | ||
* @param {React.Context} context | ||
* @returns {*} | ||
* @example | ||
* const person = useContext(PersonContext); | ||
*/ | ||
// this is not best implemented for performance, | ||
// but this wouldn't be used very often. | ||
export const useContext = context => useContextSelector(context, x => x); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
27222
112
3
177
30