react-error-boundary
Advanced tools
Comparing version 2.2.3 to 2.3.0
@@ -125,3 +125,14 @@ 'use strict'; | ||
function useErrorHandler(givenError) { | ||
var _React$useState = React.useState(null), | ||
error = _React$useState[0], | ||
setError = _React$useState[1]; | ||
if (givenError) throw givenError; | ||
if (error) throw error; | ||
return setError; | ||
} | ||
exports.ErrorBoundary = ErrorBoundary; | ||
exports.useErrorHandler = useErrorHandler; | ||
exports.withErrorBoundary = withErrorBoundary; |
@@ -119,2 +119,12 @@ import _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose'; | ||
export { ErrorBoundary, withErrorBoundary }; | ||
function useErrorHandler(givenError) { | ||
var _React$useState = React.useState(null), | ||
error = _React$useState[0], | ||
setError = _React$useState[1]; | ||
if (givenError) throw givenError; | ||
if (error) throw error; | ||
return setError; | ||
} | ||
export { ErrorBoundary, useErrorHandler, withErrorBoundary }; |
@@ -130,3 +130,14 @@ (function (global, factory) { | ||
function useErrorHandler(givenError) { | ||
var _React$useState = React.useState(null), | ||
error = _React$useState[0], | ||
setError = _React$useState[1]; | ||
if (givenError) throw givenError; | ||
if (error) throw error; | ||
return setError; | ||
} | ||
exports.ErrorBoundary = ErrorBoundary; | ||
exports.useErrorHandler = useErrorHandler; | ||
exports.withErrorBoundary = withErrorBoundary; | ||
@@ -133,0 +144,0 @@ |
@@ -1,2 +0,2 @@ | ||
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],r):r((e=e||self).ReactErrorBoundary={},e.React)}(this,(function(e,r){"use strict";r=r&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r;var t={error:null,info:null},n=function(e){var n,o;function a(){for(var r,n=arguments.length,o=new Array(n),a=0;a<n;a++)o[a]=arguments[a];return(r=e.call.apply(e,[this].concat(o))||this).state=t,r.resetErrorBoundary=function(){for(var e,n=arguments.length,o=new Array(n),a=0;a<n;a++)o[a]=arguments[a];null==r.props.onReset||(e=r.props).onReset.apply(e,o),r.setState(t)},r}o=e,(n=a).prototype=Object.create(o.prototype),n.prototype.constructor=n,n.__proto__=o;var l=a.prototype;return l.componentDidCatch=function(e,r){var t,n;null==(t=(n=this.props).onError)||t.call(n,e,null==r?void 0:r.componentStack),this.setState({error:e,info:r})},l.componentDidUpdate=function(e){var r,n,o,a,l=this.state.error,i=this.props.resetKeys;null!==l&&(void 0===(o=e.resetKeys)&&(o=[]),void 0===(a=i)&&(a=[]),o.length!==a.length||o.some((function(e,r){return!Object.is(e,a[r])})))&&(null==(r=(n=this.props).onResetKeysChange)||r.call(n,e.resetKeys,i),this.setState(t))},l.render=function(){var e=this.state,t=e.error,n=e.info,o=this.props,a=o.fallbackRender,l=o.FallbackComponent,i=o.fallback;if(null!==t){var s={componentStack:null==n?void 0:n.componentStack,error:t,resetErrorBoundary:this.resetErrorBoundary};if(r.isValidElement(i))return i;if("function"==typeof a)return a(s);if("function"==typeof l)return r.createElement(l,s);throw new Error("react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop")}return this.props.children},a}(r.Component);e.ErrorBoundary=n,e.withErrorBoundary=function(e,t){function o(o){return r.createElement(n,t,r.createElement(e,o))}var a=e.displayName||e.name||"Unknown";return o.displayName="withErrorBoundary("+a+")",o},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(r,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],e):e((r=r||self).ReactErrorBoundary={},r.React)}(this,(function(r,e){"use strict";e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e;var t={error:null,info:null},n=function(r){var n,o;function a(){for(var e,n=arguments.length,o=new Array(n),a=0;a<n;a++)o[a]=arguments[a];return(e=r.call.apply(r,[this].concat(o))||this).state=t,e.resetErrorBoundary=function(){for(var r,n=arguments.length,o=new Array(n),a=0;a<n;a++)o[a]=arguments[a];null==e.props.onReset||(r=e.props).onReset.apply(r,o),e.setState(t)},e}o=r,(n=a).prototype=Object.create(o.prototype),n.prototype.constructor=n,n.__proto__=o;var l=a.prototype;return l.componentDidCatch=function(r,e){var t,n;null==(t=(n=this.props).onError)||t.call(n,r,null==e?void 0:e.componentStack),this.setState({error:r,info:e})},l.componentDidUpdate=function(r){var e,n,o,a,l=this.state.error,i=this.props.resetKeys;null!==l&&(void 0===(o=r.resetKeys)&&(o=[]),void 0===(a=i)&&(a=[]),o.length!==a.length||o.some((function(r,e){return!Object.is(r,a[e])})))&&(null==(e=(n=this.props).onResetKeysChange)||e.call(n,r.resetKeys,i),this.setState(t))},l.render=function(){var r=this.state,t=r.error,n=r.info,o=this.props,a=o.fallbackRender,l=o.FallbackComponent,i=o.fallback;if(null!==t){var s={componentStack:null==n?void 0:n.componentStack,error:t,resetErrorBoundary:this.resetErrorBoundary};if(e.isValidElement(i))return i;if("function"==typeof a)return a(s);if("function"==typeof l)return e.createElement(l,s);throw new Error("react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop")}return this.props.children},a}(e.Component);r.ErrorBoundary=n,r.useErrorHandler=function(r){var t=e.useState(null),n=t[0],o=t[1];if(r)throw r;if(n)throw n;return o},r.withErrorBoundary=function(r,t){function o(o){return e.createElement(n,t,e.createElement(r,o))}var a=r.displayName||r.name||"Unknown";return o.displayName="withErrorBoundary("+a+")",o},Object.defineProperty(r,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=react-error-boundary.umd.min.js.map |
@@ -44,1 +44,5 @@ import * as React from 'react' | ||
): React.ComponentType<P> | ||
export function useErrorHandler<P = Error>( | ||
error?: P, | ||
): React.Dispatch<React.SetStateAction<P>> |
{ | ||
"name": "react-error-boundary", | ||
"version": "2.2.3", | ||
"version": "2.3.0", | ||
"description": "Simple reusable React error boundary component", | ||
@@ -42,15 +42,15 @@ "main": "dist/react-error-boundary.cjs.js", | ||
"dependencies": { | ||
"@babel/runtime": "^7.9.6" | ||
"@babel/runtime": "^7.10.5" | ||
}, | ||
"devDependencies": { | ||
"@testing-library/jest-dom": "^5.5.0", | ||
"@testing-library/react": "^10.0.4", | ||
"@testing-library/user-event": "^10.1.0", | ||
"kcd-scripts": "^5.11.1", | ||
"@testing-library/jest-dom": "^5.11.1", | ||
"@testing-library/react": "^10.4.7", | ||
"@testing-library/user-event": "^12.0.11", | ||
"kcd-scripts": "^6.2.4", | ||
"react": "^16.13.1", | ||
"react-dom": "^16.13.1", | ||
"typescript": "^3.8.3" | ||
"typescript": "^3.9.7" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.0.0" | ||
"react": ">=16.13.1" | ||
}, | ||
@@ -57,0 +57,0 @@ "eslintConfig": { |
137
README.md
@@ -41,10 +41,3 @@ <div align="center"> | ||
- [`ErrorBoundary` props](#errorboundary-props) | ||
- [`children`](#children) | ||
- [`FallbackComponent`](#fallbackcomponent) | ||
- [`fallbackRender`](#fallbackrender) | ||
- [`fallback`](#fallback) | ||
- [`onError`](#onerror) | ||
- [`onReset`](#onreset) | ||
- [`resetKeys`](#resetkeys) | ||
- [`onResetKeysChange`](#onresetkeyschange) | ||
- [`useErrorHandler(error?: Error)`](#useerrorhandlererror-error) | ||
- [Issues](#issues) | ||
@@ -194,3 +187,3 @@ - [๐ Bugs](#-bugs) | ||
### `children` | ||
#### `children` | ||
@@ -201,3 +194,3 @@ This is what you want rendered when everything's working fine. If there's an | ||
### `FallbackComponent` | ||
#### `FallbackComponent` | ||
@@ -211,3 +204,3 @@ This is a component you want rendered in the event of an error. As props it will | ||
### `fallbackRender` | ||
#### `fallbackRender` | ||
@@ -254,3 +247,3 @@ This is a render-prop based API that allows you to inline your error fallback UI | ||
### `fallback` | ||
#### `fallback` | ||
@@ -270,3 +263,3 @@ In the spirit of consistency with the `React.Suspense` component, we also | ||
### `onError` | ||
#### `onError` | ||
@@ -276,3 +269,3 @@ This will be called when there's been an error that the `ErrorBoundary` has | ||
### `onReset` | ||
#### `onReset` | ||
@@ -289,3 +282,3 @@ This will be called immediately before the `ErrorBoundary` resets it's internal | ||
### `resetKeys` | ||
#### `resetKeys` | ||
@@ -300,3 +293,3 @@ Sometimes an error happens as a result of local state to the component that's | ||
### `onResetKeysChange` | ||
#### `onResetKeysChange` | ||
@@ -306,2 +299,114 @@ This is called when the `resetKeys` are changed (triggering a reset of the | ||
### `useErrorHandler(error?: Error)` | ||
React's error boundaries feature is limited in that the boundaries can only | ||
handle errors thrown during React's lifecycles. To quote | ||
[the React docs on Error Boundaries](https://reactjs.org/docs/error-boundaries.html): | ||
> Error boundaries do not catch errors for: | ||
> | ||
> - Event handlers | ||
> ([learn more](https://reactjs.org/docs/error-boundaries.html#how-about-event-handlers)) | ||
> - Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks) | ||
> - Server side rendering | ||
> - Errors thrown in the error boundary itself (rather than its children) | ||
This means you have to handle those errors yourself, but you probably would like | ||
to reuse the error boundaries you worked hard on creating for those kinds of | ||
errors as well. This is what `useErrorHandler` is for. | ||
There are two ways to use `useErrorHandler`: | ||
1. `const handleError = useErrorHandler()`: call `handleError(theError)` | ||
2. `useErrorHandler(error)`: useful if you are managing the error state yourself | ||
or get it from another hook. | ||
Here's an example: | ||
```javascript | ||
function Greeting() { | ||
const [greeting, setGreeting] = React.useState(null) | ||
const handleError = useHandleError() | ||
function handleSubmit(event) { | ||
event.preventDefault() | ||
const name = event.target.elements.name.value | ||
fetchGreeting(name).then( | ||
newGreeting => setGreeting(newGreeting), | ||
handleError, | ||
) | ||
} | ||
return greeting ? ( | ||
<div>{greeting}</div> | ||
) : ( | ||
<form onSubmit={handleSubmit}> | ||
<label>Name</label> | ||
<input id="name" /> | ||
<button type="submit" onClick={handleClick}> | ||
get a greeting | ||
</button> | ||
</form> | ||
) | ||
} | ||
``` | ||
> Note, in case it's not clear what's happening here, you could also write | ||
> `handleClick` like this: | ||
```javascript | ||
function handleSubmit(event) { | ||
event.preventDefault() | ||
const name = event.target.elements.name.value | ||
fetchGreeting(name).then( | ||
newGreeting => setGreeting(newGreeting), | ||
error => handleError(error), | ||
) | ||
} | ||
``` | ||
Alternatively, let's say you're using a hook that gives you the error: | ||
```javascript | ||
function Greeting() { | ||
const [name, setName] = React.useState('') | ||
const {greeting, error} = useGreeting(name) | ||
useHandleError(error) | ||
function handleSubmit(event) { | ||
event.preventDefault() | ||
const name = event.target.elements.name.value | ||
setName(name) | ||
} | ||
return greeting ? ( | ||
<div>{greeting}</div> | ||
) : ( | ||
<form onSubmit={handleSubmit}> | ||
<label>Name</label> | ||
<input id="name" /> | ||
<button type="submit" onClick={handleClick}> | ||
get a greeting | ||
</button> | ||
</form> | ||
) | ||
} | ||
``` | ||
In this case, if the `error` is ever set to a truthy value, then it will be | ||
propagated to the nearest error boundary. | ||
In either case, you could handle those errors like this: | ||
```javascript | ||
const ui = ( | ||
<ErrorBoundary FallbackComponent={ErrorFallback}> | ||
<Greeting /> | ||
</ErrorBoundary> | ||
) | ||
``` | ||
And now that'll handle your runtime errors as well as the async errors in the | ||
`fetchGreeting` or `useGreeting` code. | ||
## Issues | ||
@@ -308,0 +413,0 @@ |
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
44098
365
445
Updated@babel/runtime@^7.10.5