-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into modal-titleonly
- Loading branch information
Showing
15 changed files
with
353 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
packages/react/src/components/ErrorBoundary/ErrorBoundary-story.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* Copyright IBM Corp. 2016, 2018 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import React, { useState } from 'react'; | ||
import { storiesOf } from '@storybook/react'; | ||
import { action } from '@storybook/addon-actions'; | ||
import { ErrorBoundary, ErrorBoundaryContext } from './'; | ||
import Button from '../Button'; | ||
|
||
storiesOf('ErrorBoundary', module) | ||
.add('default', () => { | ||
function DemoComponent() { | ||
const [shouldThrowError, setShouldThrowError] = useState(false); | ||
|
||
function onClick() { | ||
setShouldThrowError(!shouldThrowError); | ||
} | ||
|
||
return ( | ||
<> | ||
<Button onClick={onClick}>Toggle throwing error</Button> | ||
<div> | ||
<ErrorBoundary fallback={<Fallback />}> | ||
<ThrowError shouldThrowError={shouldThrowError} /> | ||
</ErrorBoundary> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
||
function Fallback() { | ||
return 'Whoops'; | ||
} | ||
|
||
function ThrowError({ shouldThrowError }) { | ||
if (shouldThrowError) { | ||
throw new Error('Component threw error'); | ||
} | ||
|
||
return 'Successfully rendered'; | ||
} | ||
|
||
return <DemoComponent />; | ||
}) | ||
.add('with custom context', () => { | ||
function DemoComponent() { | ||
const [shouldThrowError, setShouldThrowError] = useState(false); | ||
|
||
function onClick() { | ||
setShouldThrowError(!shouldThrowError); | ||
} | ||
|
||
return ( | ||
<ErrorBoundaryContext.Provider value={{ log: action('log') }}> | ||
<Button onClick={onClick}>Toggle throwing error</Button> | ||
<div> | ||
<ErrorBoundary fallback={<Fallback />}> | ||
<ThrowError shouldThrowError={shouldThrowError} /> | ||
</ErrorBoundary> | ||
</div> | ||
</ErrorBoundaryContext.Provider> | ||
); | ||
} | ||
|
||
function Fallback() { | ||
return 'Whoops'; | ||
} | ||
|
||
function ThrowError({ shouldThrowError }) { | ||
if (shouldThrowError) { | ||
throw new Error('Component threw error'); | ||
} | ||
|
||
return 'Successfully rendered'; | ||
} | ||
|
||
return <DemoComponent />; | ||
}); |
63 changes: 63 additions & 0 deletions
63
packages/react/src/components/ErrorBoundary/ErrorBoundary.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/** | ||
* Copyright IBM Corp. 2016, 2018 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { ErrorBoundaryContext } from './ErrorBoundaryContext'; | ||
|
||
/** | ||
* React introduced additional lifecycle methods in v16 for capturing errors | ||
* that occur in a specific sub-tree of components. This component helps to | ||
* consolidate some of the duplication that occurs when using these lifecycle | ||
* methods across a codebase. In addition, it allows you to specify the fallback | ||
* UI to display when an error occurs in the sub-tree through the `fallback` | ||
* prop. | ||
* | ||
* This component roughly follows the React.js docs example code for these | ||
* methods. In addition, it takes advantage of an `ErrorBoundaryContext` so that | ||
* consumers can specify their own logic for logging errors. For example, | ||
* reporting an error in the UI to an external service for every `ErrorBoundary` | ||
* used. | ||
* | ||
* Reference: | ||
* https://reactjs.org/docs/error-boundaries.html#introducing-error-boundaries | ||
*/ | ||
export default class ErrorBoundary extends React.Component { | ||
static propTypes = { | ||
children: PropTypes.node, | ||
fallback: PropTypes.node, | ||
}; | ||
|
||
static contextType = ErrorBoundaryContext; | ||
|
||
static getDerivedStateFromError() { | ||
return { | ||
hasError: true, | ||
}; | ||
} | ||
|
||
state = { | ||
hasError: false, | ||
}; | ||
|
||
componentDidCatch(error, info) { | ||
this.context.log(error, info); | ||
} | ||
|
||
componentDidUpdate(prevProps) { | ||
if (prevProps.children !== this.props.children) { | ||
this.setState({ hasError: false }); | ||
} | ||
} | ||
|
||
render() { | ||
if (this.state.hasError) { | ||
return this.props.fallback; | ||
} | ||
return this.props.children; | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
packages/react/src/components/ErrorBoundary/ErrorBoundaryContext.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/** | ||
* Copyright IBM Corp. 2016, 2018 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import { createContext } from 'react'; | ||
|
||
export const ErrorBoundaryContext = createContext({ | ||
log(error, info) { | ||
console.log(info.componentStack); | ||
}, | ||
}); |
Oops, something went wrong.