From 9343523c06bcfcd7dd688d8f526604bdc279815b Mon Sep 17 00:00:00 2001 From: Acery Date: Thu, 26 May 2022 18:59:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20React=20=E7=BB=84=E4=BB=B6=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20onError=20=E4=BA=8B=E4=BB=B6=E9=80=8F=E5=87=BA=20(#?= =?UTF-8?q?1499)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/components/tooltip/tooltip.test.tsx | 2 +- packages/react/src/index.tsx | 18 ++++- packages/react/test/chart.test.tsx | 65 ++++++++++--------- 3 files changed, 52 insertions(+), 33 deletions(-) diff --git a/packages/f2/test/components/tooltip/tooltip.test.tsx b/packages/f2/test/components/tooltip/tooltip.test.tsx index 55ece0523..cc2a3cb20 100644 --- a/packages/f2/test/components/tooltip/tooltip.test.tsx +++ b/packages/f2/test/components/tooltip/tooltip.test.tsx @@ -238,7 +238,7 @@ describe('tooltip', () => { ); await delay(10); canvas.update({ children: newChart }); - await delay(500); + await delay(1000); expect(context).toMatchImageSnapshot(); }); diff --git a/packages/react/src/index.tsx b/packages/react/src/index.tsx index 859e84909..641938912 100644 --- a/packages/react/src/index.tsx +++ b/packages/react/src/index.tsx @@ -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 { constructor(props) { super(props); this.state = { hasError: false }; @@ -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() { @@ -35,6 +45,7 @@ export interface CanvasProps { canvasRef?: RefObject; ref?: RefObject; fallback?: React.Component; + onError?: (error: Error) => void; children?: React.ReactElement | React.ReactElement[] | null; } @@ -91,9 +102,10 @@ class ReactCanvas extends React.Component { } export default forwardRef((props: CanvasProps, ref: RefObject) => { - const { fallback } = props; + const { fallback, onError } = props; return React.createElement(ErrorBoundary, { - fallback: fallback, + fallback, + onError, children: React.createElement(ReactCanvas, { ...props, ref, diff --git a/packages/react/test/chart.test.tsx b/packages/react/test/chart.test.tsx index ac1e17332..c6b707e49 100644 --- a/packages/react/test/chart.test.tsx +++ b/packages/react/test/chart.test.tsx @@ -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() }); @@ -51,31 +51,38 @@ describe('', () => { wrapper.unmount(); }); -}); -// class A extends React.Component { -// render() { -// return
A
-// } -// } - -// class B extends React.Component { -// constructor(props) { -// super(props); -// this.refA = React.createRef(); -// } - -// componentDidMount() { -// console.log(this.refA); -// } - -// render() { -// return
-// -//
-// } -// } - -// const root = document.createElement('div'); -// document.body.appendChild(root); -// ReactDOM.render(, 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( + Chart Fallback} onError={onError}> + + + ); + + // 断言 fallback 触发 + expect(wrapper.html()).toBe('
Chart Fallback
'); + + // 断言 onError 触发 + expect(onError.mock.calls.length).toBe(1); + + // reset global onerror callback + window.onerror = originOnError; + }); +});