Skip to content

Commit

Permalink
docs(suspensive.org): add ErrorBoundaryGroup examples using sandpack (#…
Browse files Browse the repository at this point in the history
…1002)

# Overview

<!--
    A clear and concise description of what this pr is about.
 -->

Add ErrorBoundaryGroup examples using sandpack.

## PR Checklist

- [x] I did below actions if need

1. I read the [Contributing
Guide](https://github.com/toss/suspensive/blob/main/CONTRIBUTING.md)
2. I added documents and tests.
  • Loading branch information
kangju2000 authored Jun 28, 2024
1 parent a7e4290 commit 5092703
Show file tree
Hide file tree
Showing 3 changed files with 372 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function App() {
},
},
dependencies: {
'@tanstack/react-query': '^4.0.0',
'@tanstack/react-query': '^4',
'@suspensive/react': 'latest',
'@suspensive/react-query': 'latest',
},
Expand Down
194 changes: 185 additions & 9 deletions docs/suspensive.org/src/pages/docs/react/ErrorBoundaryGroup.en.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Callout } from '@/components'
import { Callout, Sandpack } from '@/components'

# ErrorBoundaryGroup

Expand All @@ -15,21 +15,82 @@ const Example = () => (
<ErrorBoundaryGroup.Consumer>
{(group) => <button onClick={group.reset}>Try again</button>}
</ErrorBoundaryGroup.Consumer>
<ErrorBoundary fallback={(props) => <>{props.error}</>}>
<CanThrowError />
<ErrorBoundary fallback={(props) => <>{props.error.message}</>}>
<ErrorAfter2s />
</ErrorBoundary>
<ErrorBoundaryGroup>
<ErrorBoundaryGroup.Consumer>
{(group) => <button onClick={group.reset}>Try again</button>}
</ErrorBoundaryGroup.Consumer>
<ErrorBoundary fallback={(props) => <>{props.error}</>}>
<CanThrowError />
<ErrorBoundary fallback={(props) => <>{props.error.message}</>}>
<ErrorAfter2s />
</ErrorBoundary>
</ErrorBoundaryGroup>
</ErrorBoundaryGroup>
)
```

<Sandpack>

```tsx Example.tsx active
import { ErrorBoundaryGroup, ErrorBoundary } from '@suspensive/react'
import { ErrorAfter2s } from './ErrorAfter2s'

export const Example = () => {
return (
<ErrorBoundaryGroup>
<fieldset style={{ border: '1px solid red', padding: '10px' }}>
<legend>Outer ErrorBoundaryGroup</legend>
<ErrorBoundaryGroup.Consumer>
{(group) => <button onClick={group.reset}>Try again</button>}
</ErrorBoundaryGroup.Consumer>
<ErrorBoundary fallback={(props) => <>{props.error.message}</>}>
<ErrorAfter2s />
</ErrorBoundary>

<ErrorBoundaryGroup>
<fieldset style={{ border: '1px solid blue', padding: '10px' }}>
<legend>Inner ErrorBoundaryGroup</legend>
<ErrorBoundaryGroup.Consumer>
{(group) => <button onClick={group.reset}>Try again</button>}
</ErrorBoundaryGroup.Consumer>

<ErrorBoundary fallback={(props) => <>{props.error.message}</>}>
<ErrorAfter2s />
</ErrorBoundary>
</fieldset>
</ErrorBoundaryGroup>
</fieldset>
</ErrorBoundaryGroup>
)
}
```

```tsx ErrorAfter2s.tsx
import { useState, useEffect } from 'react'

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: { status: 401, message: 'unauthorized' } })
}, 2000)
}, [])

if (asyncState.isError) {
throw asyncState.error
}

return <>No error</>
}
```

</Sandpack>

### props.blockOutside

If you want to block resetting nested `<ErrorBoundaryGroup/>` by parent `<ErrorBoundaryGroup/>`, Use blockOutside.
Expand All @@ -42,22 +103,83 @@ const Example = () => (
<ErrorBoundaryGroup.Consumer>
{(group) => <button onClick={group.reset}>Try again</button>}
</ErrorBoundaryGroup.Consumer>
<ErrorBoundary fallback={(props) => <>{props.error}</>}>
<CanThrowError />
<ErrorBoundary fallback={(props) => <>{props.error.message}</>}>
<ErrorAfter2s />
</ErrorBoundary>

{/* blockOutside prop prevents reset by the parent ErrorBoundaryGroup*/}
<ErrorBoundaryGroup blockOutside>
<ErrorBoundaryGroup.Consumer>
{(group) => <button onClick={group.reset}>Try again</button>}
</ErrorBoundaryGroup.Consumer>
<ErrorBoundary fallback={(props) => <>{props.error}</>}>
<CanThrowError />
<ErrorBoundary fallback={(props) => <>{props.error.message}</>}>
<ErrorAfter2s />
</ErrorBoundary>
</ErrorBoundaryGroup>
</ErrorBoundaryGroup>
)
```

<Sandpack>

```tsx Example.tsx active
import { ErrorBoundaryGroup, ErrorBoundary } from '@suspensive/react'
import { ErrorAfter2s } from './ErrorAfter2s'

export const Example = () => {
return (
<ErrorBoundaryGroup>
<fieldset style={{ border: '1px solid red', padding: '10px' }}>
<legend>Outer ErrorBoundaryGroup</legend>
<ErrorBoundaryGroup.Consumer>
{(group) => <button onClick={group.reset}>Try again</button>}
</ErrorBoundaryGroup.Consumer>
<ErrorBoundary fallback={(props) => <>{props.error.message}</>}>
<ErrorAfter2s />
</ErrorBoundary>

<ErrorBoundaryGroup blockOutside>
<fieldset style={{ border: '1px solid blue', padding: '10px' }}>
<legend>Inner ErrorBoundaryGroup</legend>
<ErrorBoundaryGroup.Consumer>
{(group) => <button onClick={group.reset}>Try again</button>}
</ErrorBoundaryGroup.Consumer>
<ErrorBoundary fallback={(props) => <>{props.error.message}</>}>
<ErrorAfter2s />
</ErrorBoundary>
</fieldset>
</ErrorBoundaryGroup>
</fieldset>
</ErrorBoundaryGroup>
)
}
```

```tsx ErrorAfter2s.tsx
import { useState, useEffect } from 'react'

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: { status: 401, message: 'unauthorized' } })
}, 2000)
}, [])

if (asyncState.isError) {
throw asyncState.error
}

return <>No error</>
}
```

</Sandpack>

## useErrorBoundaryGroup

If you use useErrorBoundaryGroup, you can get a function to reset `<ErrorBoundary/>`s in `<ErrorBoundaryGroup/>`.
Expand All @@ -71,3 +193,57 @@ const Example = () => {
return <button onClick={group.reset}>Try again</button>
}
```

<Sandpack>

```tsx Button.tsx active
import { useErrorBoundaryGroup } from '@suspensive/react'

export const Button = () => {
const group = useErrorBoundaryGroup()

return <button onClick={group.reset}>Try again</button>
}
```

```tsx Example.tsx
import { ErrorBoundaryGroup, ErrorBoundary } from '@suspensive/react'
import { ErrorAfter2s } from './ErrorAfter2s'
import { Button } from './Button'

export const Example = () => {
return (
<ErrorBoundaryGroup>
<Button />
<ErrorBoundary fallback={(props) => <>{props.error.message}</>}>
<ErrorAfter2s />
</ErrorBoundary>
</ErrorBoundaryGroup>
)
}
```

```tsx ErrorAfter2s.tsx
import { useState, useEffect } from 'react'

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: { status: 401, message: 'unauthorized' } })
}, 2000)
}, [])

if (asyncState.isError) {
throw asyncState.error
}

return <>No error</>
}
```

</Sandpack>
Loading

0 comments on commit 5092703

Please sign in to comment.