(null);
+
+ useEffect(() => {
+ if (error) {
+ throw error;
+ }
+ }, [error]);
+
+ const dispatchError = useCallback((err: Error) => {
+ setError(err);
+ }, []);
+
+ return dispatchError;
+};
+
+export default useError;
diff --git a/stories/useError.story.tsx b/stories/useError.story.tsx
new file mode 100644
index 00000000..e42c8052
--- /dev/null
+++ b/stories/useError.story.tsx
@@ -0,0 +1,46 @@
+import { storiesOf } from '@storybook/react';
+import React from 'react';
+import { useError } from '../src';
+import ShowDocs from './util/ShowDocs';
+
+class ErrorBoundary extends React.Component<{}, { hasError: boolean }> {
+ constructor(props) {
+ super(props);
+ this.state = { hasError: false };
+ }
+
+ static getDerivedStateFromError(error) {
+ return { hasError: true };
+ }
+
+ render() {
+ if (this.state.hasError) {
+ return (
+
+
Something went wrong.
+
+
+ );
+ }
+
+ return this.props.children;
+ }
+}
+
+const Demo = () => {
+ const dispatchError = useError();
+
+ const clickHandler = () => {
+ dispatchError(new Error('Some error!'));
+ };
+
+ return ;
+};
+
+storiesOf('Side effects|useError', module)
+ .add('Docs', () => )
+ .add('Demo', () => (
+
+
+
+ ));
diff --git a/tests/useError.test.ts b/tests/useError.test.ts
new file mode 100644
index 00000000..2e3af244
--- /dev/null
+++ b/tests/useError.test.ts
@@ -0,0 +1,26 @@
+import { renderHook, act } from '@testing-library/react-hooks';
+import { useError } from '../src';
+
+const setup = () => renderHook(() => useError());
+
+beforeEach(() => {
+ jest.spyOn(console, 'error').mockImplementation(() => {});
+});
+
+afterEach(() => {
+ jest.clearAllMocks();
+});
+
+it('should throw an error on error dispatch', () => {
+ const errorStr = 'some_error';
+
+ try {
+ const { result } = setup();
+
+ act(() => {
+ result.current(new Error(errorStr));
+ });
+ } catch (err) {
+ expect(err.message).toEqual(errorStr);
+ }
+});