Skip to content

Commit

Permalink
feat: React 组件增加 onError 事件透出 (#1499)
Browse files Browse the repository at this point in the history
  • Loading branch information
ACERY1 committed May 26, 2022
1 parent abcd513 commit 9343523
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 33 deletions.
2 changes: 1 addition & 1 deletion packages/f2/test/components/tooltip/tooltip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ describe('tooltip', () => {
);
await delay(10);
canvas.update({ children: newChart });
await delay(500);
await delay(1000);
expect(context).toMatchImageSnapshot();
});

Expand Down
18 changes: 15 additions & 3 deletions packages/react/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React, { RefObject, forwardRef } from 'react';
import { Canvas } from '@antv/f2';

class ErrorBoundary extends React.Component<{ fallback: React.Component }, { hasError: boolean }> {
type ReactErrorBoundaryProps = {
fallback: React.Component;
onError: (error: Error) => void;
};
class ErrorBoundary extends React.Component<ReactErrorBoundaryProps, { hasError: boolean }> {
constructor(props) {
super(props);
this.state = { hasError: false };
Expand All @@ -12,7 +16,13 @@ class ErrorBoundary extends React.Component<{ fallback: React.Component }, { has
}

componentDidCatch(error, _errorInfo) {
const { onError } = this.props;

console.error('图表渲染失败: ', error);

if (typeof onError === 'function') {
onError(error);
}
}

render() {
Expand All @@ -35,6 +45,7 @@ export interface CanvasProps {
canvasRef?: RefObject<HTMLCanvasElement>;
ref?: RefObject<HTMLCanvasElement>;
fallback?: React.Component;
onError?: (error: Error) => void;
children?: React.ReactElement | React.ReactElement[] | null;
}

Expand Down Expand Up @@ -91,9 +102,10 @@ class ReactCanvas extends React.Component<CanvasProps> {
}

export default forwardRef((props: CanvasProps, ref: RefObject<HTMLCanvasElement>) => {
const { fallback } = props;
const { fallback, onError } = props;
return React.createElement(ErrorBoundary, {
fallback: fallback,
fallback,
onError,
children: React.createElement(ReactCanvas, {
...props,
ref,
Expand Down
65 changes: 36 additions & 29 deletions packages/react/test/chart.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// @ts-nocheck
/* @jsx React.createElement */
import React from 'react';
import { Canvas, Chart, Component, Line } from '@antv/f2';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import React from 'react';
import ReactCanvas from '../src';
import { Canvas, Chart, Line } from '@antv/f2';

// @ts-ignore
Enzyme.configure({ adapter: new Adapter() });
Expand Down Expand Up @@ -51,31 +51,38 @@ describe('<Canvas >', () => {

wrapper.unmount();
});
});

// class A extends React.Component {
// render() {
// return <div>A</div>
// }
// }

// class B extends React.Component {
// constructor(props) {
// super(props);
// this.refA = React.createRef();
// }

// componentDidMount() {
// console.log(this.refA);
// }

// render() {
// return <div>
// <A ref={ this.refA }></A>
// </div>
// }
// }

// const root = document.createElement('div');
// document.body.appendChild(root);
// ReactDOM.render(<B />, root);
it('Chart render with Error', () => {
const originOnError = window.onError;

// jest 内部有一些 uncaught error 会导致用例失败,所以这里需要先全局捕获一下
window.onerror = function myErrorHandler(errorMsg, url, lineNumber) {
return false;
};

class Test extends Component {
render() {
throw new Error('Render Error');
}
}

const onError = jest.fn(() => {
// do something
});

const wrapper = mount(
<ReactCanvas fallback={<div>Chart Fallback</div>} onError={onError}>
<Test />
</ReactCanvas>
);

// 断言 fallback 触发
expect(wrapper.html()).toBe('<div>Chart Fallback</div>');

// 断言 onError 触发
expect(onError.mock.calls.length).toBe(1);

// reset global onerror callback
window.onerror = originOnError;
});
});

0 comments on commit 9343523

Please sign in to comment.