๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
React

[React] ErrorBoundary๋ฅผ ํ†ตํ•œ ์„ ์–ธ์ ์ธ ์—๋Ÿฌ ํ•ธ๋“ค๋ง, react-query๋ฅผ ์ด์šฉํ•œ ์žฌํ˜ธ์ถœ ๋ฐฉ๋ฒ•

by LasBe 2023. 9. 4.
๋ฐ˜์‘ํ˜•

๐Ÿ“’ ๋ฆฌ์•กํŠธ์—์„œ์˜ ์—๋Ÿฌ ํ•ธ๋“ค๋ง


๋ฆฌ์•กํŠธ์˜ ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ ์ ˆํ•œ ์—๋Ÿฌ ํ•ธ๋“ค๋ง์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด๊ฐ€ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ €๋Š” ํ‰์†Œ API ํ˜ธ์ถœ ๋กœ์ง์— try - catch ๋ฅผ ์ด์šฉํ•ด ๊ตฌ๊ตฌ์ ˆ์ ˆ ๋ช…๋ นํ˜•์œผ๋กœ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณค ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์€ ํ•œ ์ปดํฌ๋„ŒํŠธ ์•ˆ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ, ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ,

๋‘ ๊ฐ€์ง€ ์กฐ๊ฑด์— ๋Œ€ํ•œ ๋กœ์ง์ด ์„ž์—ฌ ์ฝ”๋“œ ๋ผ์ธ ์ˆ˜๊ฐ€ ๊ธธ์–ด์ง€๊ณ  ๊ฐ€๋…์„ฑ์„ ์ €ํ•ดํ•ฉ๋‹ˆ๋‹ค.

 

๋˜ํ•œ ์—๋Ÿฌ ํ•ธ๋“ค๋ง์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ๊ธฐ์ค€์ด ์—†๋‹ค๋ฉด ๊ฐœ๋ฐœ์ž๋งˆ๋‹ค ๋‹ค๋ฅธ ์—๋Ÿฌ ํ•ธ๋“ค๋ง์œผ๋กœ ์ฝ”๋“œ์˜ ํ†ต์ผ์„ฑ์„ ์žƒ์–ด๋ฒ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<ErrorBoundary fallback={ <p>์—๋Ÿฌ ๋ฐœ์ƒ</p> }>
    <Component />
</ErrorBoundary>

ํ•˜์ง€๋งŒ ์œ„์™€ ๊ฐ™์ด ErrorBoundary๋ฅผ ์ด์šฉํ•ด ์„ ์–ธ์ ์œผ๋กœ ์—๋Ÿฌ ํ•ธ๋“ค๋ง์„ ํ•˜๊ฒŒ ๋˜๋ฉด

์—๋Ÿฌ ํ•ธ๋“ค๋ง์— ๊ด€ํ•œ ๋ชจ๋“  ๊ถŒํ•œ์„ ์œ„์ž„ํ•˜๊ฒŒ ๋˜์–ด

ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์—๋Ÿฌ ๋ฐœ์ƒ์— ๋Œ€ํ•œ ๋กœ์ง์„ ๋ฐฐ์ œํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ErrorBoundary์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

๐Ÿ“Œ ErrorBoundary

<GlobalErrorBoundary fallback={ <p>์—๋Ÿฌ ๋ฐœ์ƒ</p> }>
  <FetchErrorBoundary fallback={ <p>์—๋Ÿฌ ๋ฐœ์ƒ</p> }>
    <Component />
  </FetchErrorBoundary>
</GlobalErrorBoundary>

React 16 ๋ฒ„์ „๋ถ€ํ„ฐ Error Boundary ๊ฐœ๋…์ด ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

์ปดํฌ๋„ŒํŠธ์— ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒฝ๊ณ„๋ฅผ ๋‘˜๋Ÿฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฑ‰์€ ์—๋Ÿฌ๋ฅผ ErrorBoundary์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ ,
๋กœ๋”ฉ ์ƒํƒœ์— ๋Œ€ํ•œ fallback UI๋ฅผ ๋Œ€์ฒดํ•ด์„œ ๋ณด์—ฌ์ฃผ๋Š” Suspense์ฒ˜๋Ÿผ
์—๋Ÿฌ ์ƒํƒœ์— ๋Œ€ํ•œ fallback UI๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ๊ฒฝ๊ณ„๋ฅผ ๊ณ„์ธต๋ณ„๋กœ ๋‚˜๋ˆ  ์—๋Ÿฌ ์œ ํ˜•์— ๋”ฐ๋ผ

์ ์ ˆํ•˜๊ฒŒ ErrorBoundary๋ฅผ ๋ฐฐ์น˜ํ•˜๋ฉด ํšจ์œจ์ ์ธ ์—๋Ÿฌ ํ•ธ๋“ค๋ง์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“Œ ์ปดํฌ๋„ŒํŠธ

 

์—๋Ÿฌ ๊ฒฝ๊ณ„(Error Boundaries) – React

A JavaScript library for building user interfaces

ko.legacy.reactjs.org

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    // ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ ์„ค์ •
    this.state = { hasError: false };
  }

  // ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ
  static getDerivedStateFromError(error) {
    // ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ์—๋Ÿฌ ๋ฐœ์ƒ ์—ฌ๋ถ€๋ฅผ ํ‘œ์‹œ
    return { hasError: true };
  }

  // componentDidCatch()๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ํ›„ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ
  componentDidCatch(error, errorInfo) {
    // ์—๋Ÿฌ ์ •๋ณด์™€ ํ•จ๊ป˜ ์„œ๋น„์Šค์— ์—๋Ÿฌ ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ
    logErrorToMyService(error, errorInfo);
  }

  render() {
    // ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œ
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }

    // ์•„๋‹ˆ๋ฉด ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง
    return this.props.children;
  }
}

์œ„ ์ฝ”๋“œ๋Š” ๊ณต์‹ ๋ฌธ์„œ์—์„œ ๋ฐœ์ทŒํ•œ ErrorBoundary ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

 

ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ•๋ ฅํ•œ ๋ผ์ดํ”„ ์‚ฌ์ดํด ๊ธฐ๋Šฅ์œผ๋กœ ์—๋Ÿฌ๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—
ํ•จ์ˆ˜ํ˜•์œผ๋กœ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒŒ ํŠน์ง•์ž…๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ ์ฃผ์˜ ๊นŠ๊ฒŒ ๋ด์•ผ ํ•  ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.


๐Ÿ”Ž static getDerivedStateFromError(error)

  • ์ด ๋ฉ”์„œ๋“œ๋Š” ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ , ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•ด ์—๋Ÿฌ ๋ฐœ์ƒ ์—ฌ๋ถ€๋ฅผ ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ์— ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ํ•จ์ˆ˜๋Š” ์ปค๋ฐ‹ ๋‹จ๊ณ„์—์„œ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๋Š” ์ž‘์—…์€ ์ง€์–‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์–ด hasError ์ƒํƒœ๋ฅผ true๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž componentDidCatch(error, errorInfo)

  • ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ์บ์น˜ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ํ•จ์ˆ˜๋Š” ์ปค๋ฐ‹ ๋‹จ๊ณ„์—์„œ ํ˜ธ์ถœ๋˜๋ฉฐ, ์ฃผ๋กœ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๋Š” ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ํ˜ธ์ถœ๋˜๋ฉฐ, error ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ ๊ฐ์ฒด,
    errorInfo ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์—๋Ÿฌ ์ •๋ณด๋ฅผ ์ „๋‹ฌ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ ์—ฌ๊ธฐ์—์„œ๋Š” ์—๋Ÿฌ๋ฅผ ๋กœ๊น…ํ•˜๊ฑฐ๋‚˜ ์„œ๋น„์Šค์— ์—๋Ÿฌ ์ •๋ณด๋ฅผ ๋ณด๊ณ ํ•˜๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ react-error-boundary

$ npm install react-error-boundary

์œ„์—์„œ ์†Œ๊ฐœํ•œ ์ฝ”๋“œ์— ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ๋ถ™์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ
ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ”Ž fallback

import { ErrorBoundary } from "react-error-boundary";

<ErrorBoundary fallback={<p>์—๋Ÿฌ ๋ฐœ์ƒ</p>}>
  <Component />
</ErrorBoundary>

๊ธฐ๋ณธ์ ์ธ fallback UI๋กœ ๋Œ€์ฒดํ•˜๋Š” ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ๊ณผ ๊ฑฐ์˜ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ”Ž FallbackComponent

export const App = () => {
  return ( 
    <ErrorBoundary FallbackComponent={ErrorFallback}>
      <Component />
    </ErrorBoundary>
  )
}

export const ErrorFallback = ({ error, resetErrorBoundary }: FallbackProps) => {
  if(ํด๋ผ์ด์–ธํŠธ ์—๋Ÿฌ) return ...
  if(์„œ๋ฒ„ ์—๋Ÿฌ) return ...
  if(ํ† ํฐ ์—๋Ÿฌ) return ...
};

FallbackComponent ์†์„ฑ์€ error์™€ resetErrorBoundary ๋‘ ๊ฐœ์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.

 

error๋Š” ๋ฐœ์ƒํ•œ ์—๋Ÿฌ ๊ฐ์ฒด์ด๊ณ , resetErrorBoundary๋Š” ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ์žฌ์‹œ๋„ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

 

์ด ์†์„ฑ์„ ์ด์šฉํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•ด ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„

์—๋Ÿฌ ์œ ํ˜•๋ณ„๋กœ fallback UI๋ฅผ ์„ ํƒ์ ์œผ๋กœ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉฐ
์—๋Ÿฌ ์ฒ˜๋ฆฌ์— ๊ด€ํ•œ ๋กœ์ง์„ ์ผ๊ด„์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ“Œ API ํ˜ธ์ถœ ์žฌ์‹œ๋„

๋ชจ์ข…์˜ ์ด์œ ๋กœ API ํ˜ธ์ถœ์„ ์‹คํŒจํ–ˆ์„ ๋•Œ FallbackComponent ์†์„ฑ์˜ resetErrorBoundary๋ฅผ ํ†ตํ•ด

์žฌํ˜ธ์ถœ ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

export const App = () => {
  return ( 
    <ErrorBoundary onReset={()=>{}} FallbackComponent={ErrorFallback}>
      <Component />
    </ErrorBoundary>
  )
}

export const ErrorFallback = ({ error, resetErrorBoundary }: FallbackProps) => {
  return (
    <div>
      <p>{error.toString()}</p>
      <p>์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.</p>
      <p>์žฌ์‹œ๋„ ํ•ด์ฃผ์„ธ์š”.</p>
      <button onClick={resetErrorBoundary}>์žฌ์‹œ๋„</button>
    </div>
  );
};

์ด ๊ธฐ๋Šฅ์„ ์œ„ํ•ด์„  ErrorBoundary์˜ onReset ๋ถ€๋ถ„์— API ํ˜ธ์ถœ์„ ๋‹ด๋‹นํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋„ฃ์€ ํ›„
fallback ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์— ์ผ๋ฐ˜์ ์ธ API ํ˜ธ์ถœ ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์ฃผ์–ด๋„ ๋˜์ง€๋งŒ

react-query์—์„œ ๊ธฐ๊ฐ€ ๋ง‰ํžŒ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ”Ž QueryErrorResetBoundary

<QueryErrorResetBoundary>
  {({ reset }) => 
      <ErrorBoundary onReset={reset} FallbackComponent={ErrorFallback}>
        {children}
      </ErrorBoundary>
    )
  }
</QueryErrorResetBoundary>

// or

const { reset } = useQueryErrorResetBoundary();

<ErrorBoundary onReset={reset} FallbackComponent={ErrorFallback}>
  {children}
</ErrorBoundary>

react-query ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ด€๋ จ๋œ ์ปดํฌ๋„ŒํŠธ์ด๋ฉฐ, ์—๋Ÿฌ ์ฒ˜๋ฆฌ์™€ ๊ด€๋ จ๋œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

 

์ด ์ปดํฌ๋„ŒํŠธ๋Š” react-query์˜ Query ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด

ํ•˜์œ„ ์ฟผ๋ฆฌ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ์•Œ์•„์„œ ์žฌ์„ค์ •ํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š”๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค.

 

query๋ฅผ ์žฌ์„ค์ •ํ•˜๋Š” reset ํ•จ์ˆ˜๋ฅผ ErrorBoundary์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด

์žฌ์‚ฌ์šฉ๊ณผ API ์žฌํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ Suspense + ErrorBoundary

๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด ์ฃผ๋Š” Suspense์™€
์—๋Ÿฌ ์ƒํƒœ๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ErrorBoundary๋Š”
ํŠน์ • ์ƒํƒœ์— ๋Œ€ํ•œ ๋Œ€์ฒด UI๋ฅผ ํ‘œ์‹œํ•ด ์ค€๋‹ค๋Š” ๊ณตํ†ต์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋˜ํ•œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๋น„์Šทํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‘˜์„ ํ•ฉ์ณ (๋กœ๋”ฉ - ์—๋Ÿฌ) ์ƒํƒœ๋ฅผ

ํ†ตํ•ฉ์ ์ด๊ณ  ์„ ์–ธ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด ์ฃผ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

 

๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ์ •๋ง ๊ฐ„๋‹จํ•˜๊ฒŒ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด Suspense๋งŒ ์ถ”๊ฐ€ํ•ด ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

export const SuspenseAndErrorBoundary = ({
  children
}: {
  children: React.ReactNode;
}) => {
  const { reset } = useQueryErrorResetBoundary();
  return (
    <ErrorBoundary onReset={reset} FallbackComponent={ErrorFallback}>
      <Suspense fallback={<Loading />}>{children}</Suspense>
    </ErrorBoundary>
  );
};

export const FetchComponent = ({ queryKey }: { queryKey: number }) => {
  const { data } = useQuery(["data", queryKey], () => getFetchData(queryKey), {
    suspense: true,
    useErrorBoundary: true, // suspense์ด true์ผ ๊ฒฝ์šฐ default๋กœ true
    retry: false,
    refetchOnWindowFocus: false
  });
  return (
    <div>
      <div>ID : {data.id}</div>
      <div>Title : {data.title}</div>
    </div>
  );
};

export default function App() {
  return (
    <RootContainer>
      {[...Array(10)].map((_, idx) => {
        return (
          <Card key={idx}>
            <SuspenseAndErrorBoundary>
              <FetchComponent queryKey={idx} />
            </SuspenseAndErrorBoundary>
          </Card>
        );
      })}
    </RootContainer>
  );
}

๋ชจ๋“  ๊ธฐ๋Šฅ์„ ํ†ตํ•ฉํ•œ ์˜ˆ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

API ํ˜ธ์ถœ ์‹œ 1/4 ํ™•๋ฅ ๋กœ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ , ์ด๋ฅผ ์žฌํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

 

๊ฐœ๋ฐœ์„œ๋ฒ„์—์„œ ๋™์ž‘ํ•˜๋Š” ์˜ˆ์ œ๊ธฐ ๋•Œ๋ฌธ์— ํ‘œ์‹œ๋˜๋Š” error overlay๋Š” ๋ฌด์‹œํ•˜๊ณ  ์‹คํ–‰ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

์‹ค์ œ ์—…๋ฌด์—์„œ๋Š” ๋‹ค์–‘ํ•œ ์กฐ๊ฑด์— ๋Œ€์‘ํ•ด ์ƒํ™ฉ์— ๋งž๊ฒŒ

Props๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋„ˆ๋ฌด๋‚˜ ํŽธ๋ฆฌํ•  ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์„ ํ•ฉ๋‹ˆ๋‹ค.

 

๐Ÿ“Œ ํ”„๋กœ์ ํŠธ์— ๋„์ž…ํ•˜๊ธฐ ์œ„ํ•ด์„œ

ErrorBoundary๋ฅผ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ๋„์ž…ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋” ๋‹ค์–‘ํ•˜๊ณ  ์–ด๋ ค์šด ๋ฌธ์ œ๋“ค๊นŒ์ง€ ํ•จ๊ป˜ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋” ๊ด€์‹ฌ์ด ์žˆ์œผ์‹œ๋‹ค๋ฉด ๋‹ค์Œ ๊ธ€์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

ErrorBoundary & Suspense, ๊ฑฐ์˜ ์™„๋ฒฝํ•œ ์‚ฌ์šฉ๋ฐฉ๋ฒ• ๊ฐ€์ด๋“œ

 

[React] ErrorBoundary & Suspense, ๊ฑฐ์˜ ์™„๋ฒฝํ•œ ์‚ฌ์šฉ๋ฐฉ๋ฒ• ๊ฐ€์ด๋“œ

๐Ÿ“’ ErrorBoundary & Suspense, ๊ฑฐ์˜ ์™„๋ฒฝํ•œ ์‚ฌ์šฉ๋ฐฉ๋ฒ• ๊ฐ€์ด๋“œํ•˜๋‚˜์˜ Errorboundary ๋ฐฑ๊ฐœ์˜ try-catch ์•ˆ ๋ถ€๋Ÿฝ๋‹ค.ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ์„ ๊ณ„์†ํ•˜๋‹ค ๋ณด๋‹ˆ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์„ ๋งˆ์ฃผ์น˜๊ฒŒ ๋˜์—ˆ๊ณ , ๊ทธ์— ๋”ฐ๋ฅธ ์ ์ ˆํ•œ ํ™”๋ฉด ํ‘œํ˜„์˜ ์ค‘

lasbe.tistory.com

Suspense์„ ์‚ฌ์šฉํ•ด ์„ ์–ธ์ ์œผ๋กœ ๋กœ๋”ฉ ํ™”๋ฉด ๊ตฌํ˜„ํ•˜๊ธฐ

 

[React] Suspense์„ ์‚ฌ์šฉํ•ด ์„ ์–ธ์ ์œผ๋กœ ๋กœ๋”ฉ ํ™”๋ฉด ๊ตฌํ˜„ํ•˜๊ธฐ

๐Ÿ“’ Suspense์„ ์‚ฌ์šฉํ•ด ์„ ์–ธ์ ์œผ๋กœ ๋กœ๋”ฉ ํ™”๋ฉด ๊ตฌํ˜„ํ•˜๊ธฐ ๋ฆฌ์•กํŠธ์˜ Suspense๋Š” React 16 ๋ฒ„์ „์—์„œ ์ฒ˜์Œ์œผ๋กœ ์„ ๋ณด์ธ ํ›„ 18 ๋ฒ„์ „์œผ๋กœ ์˜ค๋ฉฐ ์ถ”๊ฐ€๋œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18์—์„œ์˜ Suspense๋ฅผ ์™œ,

lasbe.tistory.com

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€


์˜คํ”ˆ ์ฑ„ํŒ