์ค๋์ Error Boundary๋ผ๋ ๊ฒ์ ๋ํด ์์๋ณผ๊ป์
๊ณต์๋ฌธ์ ๋ณด๋ค๊ฐ ๋ฐ๊ฒฌํ์ด์ ํํ
: ํ์ ์ปดํฌ๋ํธ ํธ๋ฆฌ์ ์ด๋์์๋ ์๋ฐ์คํฌ๋ฆฝํธ ์๋ฌ๋ฅผ ๊ธฐ๋กํ๋ฉฐ ๊นจ์ง ์ปดํฌ๋ํธ ํธ๋ฆฌ ๋์ ํด๋ฐฑ UI๋ฅผ ๋ณด์ฌ์ฃผ๋ React ์ปดํฌ๋ํธ
๊ณผ๊ฑฐ์๋ ์ปดํฌ๋ํธ ๋ด๋ถ์ ์๋ฐ์คํฌ๋ฆฝํธ ์๋ฌ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์๋๋ฐ, ์ด์ ์๋ฌ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์ค์ ํด์ฃผ๋ฉด ๋ฐ์ด๋๋ฆฌ ๋ด์ ์ปดํฌ๋ํธ์ ๊ทธ ํ์ ์ปดํฌ๋ํธ์์ ๋ฐ์ํ๋ ์๋ฌ๋ฅผ ๊ฐ์งํด์ fallback UI๋ฅผ ๋์ด์ค ์ ์๊ฒ ๋๊ฒ์ด๋ค!!
ํด๋์ค ์ปดํฌ๋ํธ๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ณ ํจ์ํ์์๋ react-error-boundary๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ฌ ํ์ด์ง๋ฅผ ๋ณด์ฌ์ค ์ ์๋ค
๋ชจ๋ ์๋ฌ์์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ฒ์ ์๋๋ค
์์ธ์ฌํญ๋ค์ ๋ค์๊ณผ ๊ฐ๋ค.
๐จ ์์ธ
1. ์ด๋ฒคํธ ํธ๋ค๋ฌ
2. ๋น๋๊ธฐ์ ์ฝ๋ (์: setTimeout ํน์ requestAnimationFrame ์ฝ๋ฐฑ)
3. ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง
4. ์์์์๊ฐ ์๋ ์๋ฌ ๊ฒฝ๊ณ ์์ฒด์์ ๋ฐ์ํ๋ ์๋ฌ
ํนํ 4๋ฒ์งธ ์์ธ๋ฅผ ์ฃผ์ํด์ ๋ด์ผํ๋ค.
Error boundary๋ ํธ๋ฆฌ ๋ด์์ ์์ ๋ณด๋ค ํ์์ ์กด์ฌํ๋ ์ปดํฌ๋ํธ์ ๋ํ ์ค๋ฅ๋ง์ ๊ฐ์งํด๋ด๋ฏ๋ก ์ฆ , ์๊ธฐ ์์ ์ ๋ํ ์ค๋ฅ๋ ๊ฐ์งํ ์ ์๋ค๋ ๊ฒ์ด๋ค.
์๋ช ์ฃผ๊ธฐ ๋ฉ์๋์ธ static getDerivedStateFromError() ์ componentDidCatch() ์ค ํ๋ (ํน์ ๋ ๋ค)๋ฅผ ์ ์ํ๋ฉด ํด๋์ค ์ปดํฌ๋ํธ ์์ฒด๊ฐ ์๋ฌ ๊ฒฝ๊ณ๊ฐ ๋๋ค.
1๏ธโฃ ์๋ฌ๊ฐ ๋ฐ์ํ ๋ค์ ํด๋ฐฑ UI๋ฅผ ๋ ๋๋งํ ๋
โก๏ธ static getDerivedStateFromError()
2๏ธโฃ ์๋ฌ ์ ๋ณด ๊ธฐ๋กํ ๋
โก๏ธ componentDidCatch()
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// ๋ค์ ๋ ๋๋ง์์ ํด๋ฐฑ UI๊ฐ ๋ณด์ด๋๋ก ์ํ๋ฅผ ์
๋ฐ์ดํธ ํฉ๋๋ค.
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// ์๋ฌ ๋ฆฌํฌํ
์๋น์ค์ ์๋ฌ๋ฅผ ๊ธฐ๋กํ ์๋ ์์ต๋๋ค.
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// ํด๋ฐฑ UI๋ฅผ ์ปค์คํ
ํ์ฌ ๋ ๋๋งํ ์ ์์ต๋๋ค.
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
๊ทธ๋ฆฌ๊ณ ์ผ๋ฐ์ปดํฌ๋ํธ์ ์ด๋ฐ์์ผ๋ก ์ฌ์ฉํ๋ค
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
try/catch ์ Error Boundary ๋ชจ๋ ์์ธ ์ํฉ์ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉํ๋ค๋ ์ ์์ ๋น์ทํ๋ค.
๋์ ์ฐจ์ด๋ ์ด๋ค๊ฒ ์๋์ง ์์๋ณด์
๋ช ๋ นํ ์ฝ๋์์๋ง ๋์ํ๋ค. ๋ช ๋ นํ ์ฝ๋๋ ์ด๋ป๊ฒ(How) ๋์ํ ์ง๋ฅผ ๋ช ํํ๊ฒ ์ง์ํ๋ ๋ฐฉ์์ด๋ค.
try {
showButton();
} catch (error) {
// ...
}
๊ทธ๋ฌ๋ ๋ฆฌ์กํธ๋ ์ ์ธ์ ์ด๋ค.์ ์ธ์ ์ฝ๋๋ ๋ฌด์(What)์ ๋ ๋๋งํ ์ง ์ ์ธํ๊ณ , ์ด๋ป๊ฒ(How) ๋ ๋๋ง๋ ์ง๋ React๊ฐ ๊ด๋ฆฌํ๋ค. ๋ช ๋ นํ ์ฝ๋์ธ try/catch์ ๋ค๋ฅด๊ฒ Error Boundary๋ ์ด๋ฌํ React์ ์ ์ธ์ ์ธ ํน์ฑ์ ๋ณด์กดํ์ฌ ๋์ํ๋ค
const App = () => (
<div>
<Button />
</div>
);