diff --git a/.changeset/afraid-suns-decide.md b/.changeset/afraid-suns-decide.md new file mode 100644 index 000000000..0775ede6e --- /dev/null +++ b/.changeset/afraid-suns-decide.md @@ -0,0 +1,5 @@ +--- +"@suspensive/react": patch +--- + +fix(react): add jsdoc for shouldCatch prop of ErrorBoundary diff --git a/configs/tsup/src/index.ts b/configs/tsup/src/index.ts index f1820e426..d8613547f 100644 --- a/configs/tsup/src/index.ts +++ b/configs/tsup/src/index.ts @@ -1,7 +1,6 @@ import type { Options } from 'tsup' export const options: Options = { - clean: true, banner: { js: '"use client"' }, format: ['cjs', 'esm'], target: ['chrome51', 'firefox53', 'edge18', 'safari11', 'ios11', 'opera38', 'es6', 'node14'], @@ -12,7 +11,6 @@ export const options: Options = { } export const scriptOptions: Options = { - clean: true, format: ['cjs'], target: ['chrome51', 'firefox53', 'edge18', 'safari11', 'ios11', 'opera38', 'es6', 'node14'], entry: ['src/scripts/*.{ts,tsx}', '!**/*.{spec,test,test-d,bench}.*'], diff --git a/docs/suspensive.org/src/pages/docs/react/ErrorBoundary.en.mdx b/docs/suspensive.org/src/pages/docs/react/ErrorBoundary.en.mdx index 20aede6e0..211627080 100644 --- a/docs/suspensive.org/src/pages/docs/react/ErrorBoundary.en.mdx +++ b/docs/suspensive.org/src/pages/docs/react/ErrorBoundary.en.mdx @@ -1,4 +1,5 @@ import { Callout, Sandpack } from '@/components' +import { Tabs } from 'nextra/components' # ErrorBoundary @@ -61,7 +62,7 @@ export const ErrorAfter2s = () => { useEffect(() => { setTimeout(() => { - setAsyncState({ isError: true, error: { status: 401, message: 'unauthorized' } }) + setAsyncState({ isError: true, error: new Error('error made by Error') }) }, 2000) }, []) @@ -196,7 +197,7 @@ export const ErrorAfter2s = () => { useEffect(() => { setTimeout(() => { - setAsyncState({ isError: true, error: { status: 401, message: 'unauthorized' } }) + setAsyncState({ isError: true, error: new Error('error made by Error') }) }, 2000) }, []) @@ -350,7 +351,202 @@ export const ErrorAfter2s = () => { useEffect(() => { setTimeout(() => { - setAsyncState({ isError: true, error: { status: 401, message: 'unauthorized' } }) + setAsyncState({ isError: true, error: new Error('error made by Error') }) + }, 2000) + }, []) + + if (asyncState.isError) { + throw asyncState.error + } + + return <>No error +} +``` + + + +### props.shouldCatch + +shouldCatch determines whether `` should catch errors based on conditions. + +It accepts three criteria: Boolean, ErrorConstructor, and Callback, and defaults to true. + + + + +```tsx /shouldCatch/ +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} +``` + + + + +```tsx /shouldCatch/ +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} +``` + + + + +```tsx /shouldCatch/ +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + error instanceof CustomError} + fallback={({ error }) => <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} +``` + + + + +You can also apply multiple criteria through array. + +```tsx /shouldCatch/ +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + error instanceof CustomError]} + fallback={({ error }) => <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} +``` + + + +```tsx Example.tsx active +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} + +export class CustomError extends Error { + constructor(...args: ConstructorParameters) { + super(...args) + console.error(...args) + } +} + +export const CustomErrorAfter2s = () => { + const [asyncState, setAsyncState] = useState< + { isError: true; error: CustomError } | { isError: false; error: null } + >({ + isError: false, + error: null + }); + + useEffect(() => { + setTimeout(() => { + setAsyncState({ + isError: true, + error: () => new CustomError("error made by CustomError") + }); + }, 2000); + }, []); + + if (asyncState.isError) { + throw asyncState.error(); + } + + return <>No error; +}; +``` + + + +
+ + + +```tsx Example.tsx active +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} + +export class CustomError extends Error { + constructor(...args: ConstructorParameters) { + super(...args) + console.error(...args) + } +} + +export const ErrorAfter2s = () => { + const [asyncState, setAsyncState] = useState<{ isError: true; error: Error } | { isError: false; error: null }>({ + isError: false, + error: null, + }) + + useEffect(() => { + setTimeout(() => { + setAsyncState({ isError: true, error: new Error('error made by Error') }) }, 2000) }, []) diff --git a/docs/suspensive.org/src/pages/docs/react/ErrorBoundary.ko.mdx b/docs/suspensive.org/src/pages/docs/react/ErrorBoundary.ko.mdx index c10fc7214..0ce3014d2 100644 --- a/docs/suspensive.org/src/pages/docs/react/ErrorBoundary.ko.mdx +++ b/docs/suspensive.org/src/pages/docs/react/ErrorBoundary.ko.mdx @@ -1,4 +1,5 @@ import { Callout, Sandpack } from '@/components' +import { Tabs } from 'nextra/components' # ErrorBoundary @@ -61,7 +62,7 @@ export const ErrorAfter2s = () => { useEffect(() => { setTimeout(() => { - setAsyncState({ isError: true, error: { status: 401, message: 'unauthorized' } }) + setAsyncState({ isError: true, error: new Error('error made by Error') }) }, 2000) }, []) @@ -201,7 +202,7 @@ export const ErrorAfter2s = () => { useEffect(() => { setTimeout(() => { - setAsyncState({ isError: true, error: { status: 401, message: 'unauthorized' } }) + setAsyncState({ isError: true, error: new Error('error made by Error') }) }, 2000) }, []) @@ -354,7 +355,204 @@ export const ErrorAfter2s = () => { useEffect(() => { setTimeout(() => { - setAsyncState({ isError: true, error: { status: 401, message: 'unauthorized' } }) + setAsyncState({ isError: true, error: new Error('error made by Error') }) + }, 2000) + }, []) + + if (asyncState.isError) { + throw asyncState.error + } + + return <>No error +} +``` + + + +### props.shouldCatch + +shouldCatch는 조건에 따라 ``가 에러를 잡을지 결정합니다. + +Boolean, ErrorConstructor, Callback의 3가지 기준을 받으며 기본값은 `true`입니다. + + + + +```tsx /shouldCatch/ +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} +``` + + + + +```tsx /shouldCatch/ +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} +``` + + + + +```tsx /shouldCatch/ +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + error instanceof CustomError} + fallback={({ error }) => <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} +``` + + + + +배열을 통해 여러 조건을 적용할 수도 있습니다. + +```tsx /shouldCatch/ +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + error instanceof CustomError]} + fallback={({ error }) => <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} +``` + + + +```tsx Example.tsx active +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} + + +export class CustomError extends Error { + constructor(...args: ConstructorParameters) { + super(...args) + console.error(...args) + } +} + +export const CustomErrorAfter2s = () => { + const [asyncState, setAsyncState] = useState< + { isError: true; error: CustomError } | { isError: false; error: null } + >({ + isError: false, + error: null + }); + + useEffect(() => { + setTimeout(() => { + setAsyncState({ + isError: true, + error: () => new CustomError("error made by CustomError") + }); + }, 2000); + }, []); + + if (asyncState.isError) { + throw asyncState.error(); + } + + return <>No error; +}; +``` + + + +
+ + + +```tsx Example.tsx active +import { ErrorBoundary } from '@suspensive/react' +import { useState, useEffect, createElement } from 'react' + + +export const Example = () => { + return ( + <>Parent ErrorBoundary fallback: {error.message}}> + <>Child ErrorBoundary fallback: {error.message}} + > + + + + ) +} + +export class CustomError extends Error { + constructor(...args: ConstructorParameters) { + super(...args) + console.error(...args) + } +} + +export const ErrorAfter2s = () => { + const [asyncState, setAsyncState] = useState<{ isError: true; error: Error } | { isError: false; error: null }>({ + isError: false, + error: null, + }) + + useEffect(() => { + setTimeout(() => { + setAsyncState({ isError: true, error: new Error('error made by Error') }) }, 2000) }, []) diff --git a/packages/react/src/ErrorBoundary.tsx b/packages/react/src/ErrorBoundary.tsx index 70c9d3533..1b3f882bf 100644 --- a/packages/react/src/ErrorBoundary.tsx +++ b/packages/react/src/ErrorBoundary.tsx @@ -65,6 +65,7 @@ export type ErrorBoundaryProps = PropsWithDevMode< */ fallback: ReactNode | FunctionComponent /** + * determines whether the ErrorBoundary should catch errors based on conditions * @default true */ shouldCatch?: ShouldCatch | [ShouldCatch, ...ShouldCatch[]]