๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ์ ์ ์์ ์ธ UI ์ฅ์ ๊ทน๋ณต์ ์ํด React์์ JavaScript ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ดํดํ๊ณ ๊ตฌํํ๋ ์ข ํฉ ๊ฐ์ด๋์ ๋๋ค.
JavaScript ์ค๋ฅ ๊ฒฝ๊ณ(Error Boundary): React ์ค๋ฅ ์ฒ๋ฆฌ ๊ตฌํ ๊ฐ์ด๋
React ๊ฐ๋ฐ ์์ญ์์ ์๊ธฐ์น ์์ ์ค๋ฅ๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ํดํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ถ์์ ์ฑ์ ์ด๋ํ ์ ์์ต๋๋ค. ์ ์ ์๋ ์ค๋ฅ ์ฒ๋ฆฌ ์ ๋ต์ ๊ฒฌ๊ณ ํ๊ณ ์ ๋ขฐํ ์ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. React์ ์ค๋ฅ ๊ฒฝ๊ณ(Error Boundaries)๋ ์ปดํฌ๋ํธ ํธ๋ฆฌ ๋ด์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๋จ์ ๋ฐฉ์งํ๊ณ ๋์ฒด UI๋ฅผ ํ์ํ ์ ์๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค.
์ค๋ฅ ๊ฒฝ๊ณ(Error Boundary)๋ ๋ฌด์์ธ๊ฐ์?
์ค๋ฅ ๊ฒฝ๊ณ๋ ์์ ์ปดํฌ๋ํธ ํธ๋ฆฌ ์ด๋์์๋ JavaScript ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ์ฌ ๊ธฐ๋กํ๊ณ , ์ถฉ๋์ด ๋ฐ์ํ ์ปดํฌ๋ํธ ํธ๋ฆฌ ๋์ ๋์ฒด UI๋ฅผ ํ์ํ๋ React ์ปดํฌ๋ํธ์ ๋๋ค. ์ค๋ฅ ๊ฒฝ๊ณ๋ ๋ ๋๋ง ์ค, ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋, ๊ทธ๋ฆฌ๊ณ ํ์ ์ ์ฒด ํธ๋ฆฌ์ ์์ฑ์์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํฉ๋๋ค.
์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ React ์ปดํฌ๋ํธ๋ฅผ ์ํ try...catch
๋ธ๋ก์ด๋ผ๊ณ ์๊ฐํ ์ ์์ต๋๋ค. try...catch
๋ธ๋ก์ด ๋๊ธฐ์ ์ธ JavaScript ์ฝ๋์์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ฒ๋ผ, ์ค๋ฅ ๊ฒฝ๊ณ๋ React ์ปดํฌ๋ํธ ๋ ๋๋ง ์ค์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ ์ ์๊ฒ ํด์ค๋๋ค.
์ค์ ์ฐธ๊ณ : ์ค๋ฅ ๊ฒฝ๊ณ๋ ๋ค์ ๊ฒฝ์ฐ์ ์ค๋ฅ๋ ํฌ์ฐฉํ์ง ์์ต๋๋ค:
- ์ด๋ฒคํธ ํธ๋ค๋ฌ (๋ค์ ์น์ ์์ ์์ธํ ์์๋ณด๊ธฐ)
- ๋น๋๊ธฐ ์ฝ๋ (์:
setTimeout
๋๋requestAnimationFrame
์ฝ๋ฐฑ) - ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง
- ์ค๋ฅ ๊ฒฝ๊ณ ์์ฒด์์ ๋ฐ์ํ๋ ์ค๋ฅ (์์ ์ปดํฌ๋ํธ๊ฐ ์๋)
์ ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ฌ์ฉํด์ผ ํ๋์?
์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ๊ฐ์ง ์ค์ํ ์ด์ ์ด ์์ต๋๋ค:
- ํฅ์๋ ์ฌ์ฉ์ ๊ฒฝํ: ๋น ํฐ์ ํ๋ฉด์ด๋ ์ ์ ์๋ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ๋์ , ์ฌ์ฉ์ ์นํ์ ์ธ ๋์ฒด UI๋ฅผ ๋ณด์ฌ์ฃผ์ด ์ฌ์ฉ์์๊ฒ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์์ ์๋ฆฌ๊ณ ์ ์ฌ์ ์ผ๋ก ๋ณต๊ตฌํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ ์ ์์ต๋๋ค (์: ํ์ด์ง ์๋ก๊ณ ์นจ ๋๋ ๋ค๋ฅธ ์น์ ์ผ๋ก ์ด๋).
- ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฑ: ์ค๋ฅ ๊ฒฝ๊ณ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ ๋ถ๋ถ์์ ๋ฐ์ํ ์ค๋ฅ๊ฐ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๋จ์ํค๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. ์ด๋ ์ํธ ์ฐ๊ฒฐ๋ ์ปดํฌ๋ํธ๊ฐ ๋ง์ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์์ ํนํ ์ค์ํฉ๋๋ค.
- ์ค์ ์ง์ค์ ์ค๋ฅ ์ฒ๋ฆฌ: ์ค๋ฅ ๊ฒฝ๊ณ๋ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ๊ณ ๋ฌธ์ ์ ๊ทผ๋ณธ ์์ธ์ ์ถ์ ํ ์ ์๋ ์ค์ ์ง์ค์ ์์น๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๋๋ฒ๊น ๊ณผ ์ ์ง๋ณด์๋ฅผ ๋จ์ํํฉ๋๋ค.
- ์ ์์ ์ธ ๊ธฐ๋ฅ ์ ํ(Graceful Degradation): ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์ ์ ๋ต์ ์ผ๋ก ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ๋ฐฐ์นํ์ฌ ์ผ๋ถ ์ปดํฌ๋ํธ๊ฐ ์คํจํ๋๋ผ๋ ๋๋จธ์ง ์ ํ๋ฆฌ์ผ์ด์ ์ด ๊ณ์ ์๋ํ๋๋ก ํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ค๋ฅ ๋ฐ์ ์ ์ ์์ ์ธ ๊ธฐ๋ฅ ์ ํ๊ฐ ๊ฐ๋ฅํด์ง๋๋ค.
React์์ ์ค๋ฅ ๊ฒฝ๊ณ ๊ตฌํํ๊ธฐ
์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์์ฑํ๋ ค๋ฉด ๋ค์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋ ์ค ํ๋ ๋๋ ๋ ๋ค๋ฅผ ๊ตฌํํ๋ ํด๋์ค ์ปดํฌ๋ํธ๋ฅผ ์ ์ํด์ผ ํฉ๋๋ค:
static getDerivedStateFromError(error)
: ์ด ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ ํ์ ์ปดํฌ๋ํธ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ์ ํธ์ถ๋ฉ๋๋ค. ๋ฐ์ํ ์ค๋ฅ๋ฅผ ์ธ์๋ก ๋ฐ์ผ๋ฉฐ, ์ค๋ฅ๊ฐ ๋ฐ์ํ์์ ๋ํ๋ด๊ธฐ ์ํด ์ปดํฌ๋ํธ์ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ ๊ฐ์ ๋ฐํํด์ผ ํฉ๋๋ค (์:hasError
ํ๋๊ทธ๋ฅผtrue
๋ก ์ค์ ).componentDidCatch(error, info)
: ์ด ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ ํ์ ์ปดํฌ๋ํธ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ์ ํธ์ถ๋ฉ๋๋ค. ๋ฐ์ํ ์ค๋ฅ์ ํจ๊ป ์ด๋ค ์ปดํฌ๋ํธ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋์ง์ ๋ํ ์ ๋ณด๊ฐ ํฌํจ๋info
๊ฐ์ฒด๋ฅผ ์ธ์๋ก ๋ฐ์ต๋๋ค. ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ Sentry๋ Bugsnag ๊ฐ์ ์๋น์ค์ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ ์ ์์ต๋๋ค.
๋ค์์ ์ค๋ฅ ๊ฒฝ๊ณ ์ปดํฌ๋ํธ์ ๊ธฐ๋ณธ ์์์ ๋๋ค:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: null
};
}
static getDerivedStateFromError(error) {
// ๋ค์ ๋ ๋๋ง์์ ๋์ฒด UI๋ฅผ ํ์ํ๋๋ก ์ํ๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค.
return {
hasError: true,
error: error
};
}
componentDidCatch(error, info) {
// "componentStack" ์์:
// in ComponentThatThrows (created by App)
// in MyErrorBoundary (created by App)
// in div (created by App)
// in App
console.error("Caught an error:", error, info);
this.setState({
errorInfo: info.componentStack
});
// ์ค๋ฅ ๋ณด๊ณ ์๋น์ค์ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ ์๋ ์์ต๋๋ค
//logErrorToMyService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
// ์ํ๋ ์ฌ์ฉ์ ์ ์ ๋์ฒด UI๋ฅผ ๋ ๋๋งํ ์ ์์ต๋๋ค
return (
<div>
<h2>๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.</h2>
<p>์ค๋ฅ: {this.state.error ? this.state.error.message : "์ ์ ์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค."}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.errorInfo && this.state.errorInfo}
</details>
</div>
);
}
return this.props.children;
}
}
์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋ณดํธํ๋ ค๋ ์ปดํฌ๋ํธ ํธ๋ฆฌ๋ฅผ ๊ฐ์ธ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค:
<ErrorBoundary>
<MyComponentThatMightThrow/>
</ErrorBoundary>
์ค๋ฅ ๊ฒฝ๊ณ ์ฌ์ฉ์ ์ค์ ์์
์ค๋ฅ ๊ฒฝ๊ณ๊ฐ ํนํ ์ ์ฉํ ์ ์๋ ๋ช ๊ฐ์ง ์ค์ ์๋๋ฆฌ์ค๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
1. API ์ค๋ฅ ์ฒ๋ฆฌ
API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ๋คํธ์ํฌ ๋ฌธ์ , ์๋ฒ ๋ฌธ์ ๋๋ ์ ํจํ์ง ์์ ๋ฐ์ดํฐ๋ก ์ธํด ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ํ์ํ๋ ์ปดํฌ๋ํธ๋ฅผ ์ค๋ฅ ๊ฒฝ๊ณ๋ก ๊ฐ์ธ ์ด๋ฌํ ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
function UserProfile() {
const [user, setUser] = React.useState(null);
const [isLoading, setIsLoading] = React.useState(true);
React.useEffect(() => {
async function fetchData() {
try {
const response = await fetch('/api/user');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (error) {
// ์ค๋ฅ๋ ErrorBoundary์ ์ํด ํฌ์ฐฉ๋ฉ๋๋ค
throw error;
} finally {
setIsLoading(false);
}
}
fetchData();
}, []);
if (isLoading) {
return <p>์ฌ์ฉ์ ํ๋กํ ๋ก๋ฉ ์ค...</p>;
}
if (!user) {
return <p>์ฌ์ฉ์ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.</p>;
}
return (
<div>
<h2>{user.name}</h2>
<p>์ด๋ฉ์ผ: {user.email}</p>
</div>
);
}
function App() {
return (
<ErrorBoundary>
<UserProfile />
</ErrorBoundary>
);
}
์ด ์์์์ API ํธ์ถ์ด ์คํจํ๊ฑฐ๋ ์ค๋ฅ๋ฅผ ๋ฐํํ๋ฉด ์ค๋ฅ ๊ฒฝ๊ณ๊ฐ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ณ (์ค๋ฅ ๊ฒฝ๊ณ์ render
๋ฉ์๋ ๋ด์ ์ ์๋) ๋์ฒด UI๋ฅผ ํ์ํฉ๋๋ค. ์ด๋ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์
์ ์ค๋จ์ ๋ฐฉ์งํ๊ณ ์ฌ์ฉ์์๊ฒ ๋ ์ ์ตํ ๋ฉ์์ง๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋์ฒด UI๋ฅผ ํ์ฅํ์ฌ ์์ฒญ์ ์ฌ์๋ํ๋ ์ต์
์ ์ ๊ณตํ ์๋ ์์ต๋๋ค.
2. ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค๋ฅ ์ฒ๋ฆฌ
์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๋ ์๊ธฐ์น ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๋ฅผ ์ค๋ฅ ๊ฒฝ๊ณ๋ก ๊ฐ์ธ๋ฉด ์ด๋ฌํ ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ ๋ถ์ผ์น๋ ๋ค๋ฅธ ๋ฌธ์ ๋ก ์ธํด ๊ฐ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ๊ฐ์์ ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์๊ฐํด๋ณด์ธ์. ๋ค์๊ณผ ๊ฐ์ด ์ฐจํธ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ ์ ์์ต๋๋ค:
function MyChartComponent() {
try {
// ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฐจํธ ๋ ๋๋ง
return <Chart data={data} />;
} catch (error) {
// ์ด catch ๋ธ๋ก์ React ์ปดํฌ๋ํธ ์๋ช
์ฃผ๊ธฐ ์ค๋ฅ์๋ ํจ๊ณผ๊ฐ ์์ต๋๋ค
// ์ฃผ๋ก ์ด ํน์ ํจ์ ๋ด์ ๋๊ธฐ์ ์ค๋ฅ๋ฅผ ์ํ ๊ฒ์
๋๋ค.
console.error("Error rendering chart:", error);
// ErrorBoundary๊ฐ ํฌ์ฐฉํ๋๋ก ์ค๋ฅ๋ฅผ ๋์ง๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์
throw error; // ์ค๋ฅ ๋ค์ ๋์ง๊ธฐ
}
}
function App() {
return (
<ErrorBoundary>
<MyChartComponent />
</ErrorBoundary>
);
}
๋ง์ฝ Chart
์ปดํฌ๋ํธ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์ค๋ฅ ๊ฒฝ๊ณ๊ฐ ์ด๋ฅผ ํฌ์ฐฉํ๊ณ ๋์ฒด UI๋ฅผ ํ์ํฉ๋๋ค. MyChartComponent ๋ด์ try/catch๋ ์ปดํฌ๋ํธ์ ์๋ช
์ฃผ๊ธฐ๊ฐ ์๋ ๋๊ธฐ ํจ์ ๋ด์ ์ค๋ฅ๋ง ํฌ์ฐฉํ๋ค๋ ์ ์ ์ ์ํ์ธ์. ๋ฐ๋ผ์ ์ฌ๊ธฐ์ ์ค๋ฅ ๊ฒฝ๊ณ๋ ๋งค์ฐ ์ค์ํฉ๋๋ค.
3. ๋ ๋๋ง ์ค๋ฅ ์ฒ๋ฆฌ
์ ํจํ์ง ์์ ๋ฐ์ดํฐ, ์๋ชป๋ prop ํ์ ๋๋ ๊ธฐํ ๋ฌธ์ ๋ก ์ธํด ๋ ๋๋ง ๊ณผ์ ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ค๋ฅ ๊ฒฝ๊ณ๋ ์ด๋ฌํ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ค๋จ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
function DisplayName({ name }) {
if (typeof name !== 'string') {
throw new Error('Name must be a string');
}
return <h2>์๋
ํ์ธ์, {name}๋!</h2>;
}
function App() {
return (
<ErrorBoundary>
<DisplayName name={123} /> <!-- ์๋ชป๋ prop ํ์
-->
</ErrorBoundary>
);
}
์ด ์์์์ DisplayName
์ปดํฌ๋ํธ๋ name
prop์ด ๋ฌธ์์ด์ผ ๊ฒ์ผ๋ก ์์ํฉ๋๋ค. ๋์ ์ซ์๊ฐ ์ ๋ฌ๋๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ณ ์ค๋ฅ ๊ฒฝ๊ณ๊ฐ ์ด๋ฅผ ํฌ์ฐฉํ์ฌ ๋์ฒด UI๋ฅผ ํ์ํฉ๋๋ค.
์ค๋ฅ ๊ฒฝ๊ณ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ
์์ ์ธ๊ธํ๋ฏ์ด, ์ค๋ฅ ๊ฒฝ๊ณ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ์ง ์์ต๋๋ค. ์ด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ผ๋ฐ์ ์ผ๋ก ๋น๋๊ธฐ์ ์ด๋ฉฐ, ์ค๋ฅ ๊ฒฝ๊ณ๋ ๋ ๋๋ง ์ค, ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋, ๊ทธ๋ฆฌ๊ณ ์์ฑ์์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ง ํฌ์ฐฉํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ ํจ์ ๋ด์์ ์ ํต์ ์ธ try...catch
๋ธ๋ก์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
function MyComponent() {
const handleClick = () => {
try {
// ์ค๋ฅ๋ฅผ ๋ฐ์์ํฌ ์ ์๋ ์ผ๋ถ ์ฝ๋
throw new Error('์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค');
} catch (error) {
console.error('์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ์ต๋๋ค:', error);
// ์ค๋ฅ ์ฒ๋ฆฌ (์: ์ฌ์ฉ์์๊ฒ ์ค๋ฅ ๋ฉ์์ง ํ์)
}
};
return <button onClick={handleClick}>ํด๋ฆญํ์ธ์</button>;
}
์ ์ญ ์ค๋ฅ ์ฒ๋ฆฌ
์ค๋ฅ ๊ฒฝ๊ณ๋ React ์ปดํฌ๋ํธ ํธ๋ฆฌ ๋ด์ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ํ๋ฅญํ์ง๋ง, ๋ชจ๋ ๊ฐ๋ฅํ ์ค๋ฅ ์๋๋ฆฌ์ค๋ฅผ ๋ค๋ฃจ์ง๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ ์ญ ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ์ค๋ฅ๋ React๊ฐ ์ด๊ธฐํ๋๊ธฐ ์ ์ ์คํ๋๋ ์ฝ๋์ ์ค๋ฅ์ ๊ฐ์ด React ์ปดํฌ๋ํธ ์ธ๋ถ์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ ํฌ์ฐฉํ์ง ๋ชปํฉ๋๋ค.
์ด๋ฌํ ์ ํ์ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด window.onerror
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
window.onerror = function(message, source, lineno, colno, error) {
console.error('์ ์ญ ์ค๋ฅ ํธ๋ค๋ฌ:', message, source, lineno, colno, error);
// Sentry๋ Bugsnag ๊ฐ์ ์๋น์ค์ ์ค๋ฅ ๊ธฐ๋ก
// ์ฌ์ฉ์์๊ฒ ์ ์ญ ์ค๋ฅ ๋ฉ์์ง ํ์ (์ ํ ์ฌํญ)
return true; // ๊ธฐ๋ณธ ์ค๋ฅ ์ฒ๋ฆฌ ๋์ ๋ฐฉ์ง
};
window.onerror
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ํฌ์ฐฉ๋์ง ์์ JavaScript ์ค๋ฅ๊ฐ ๋ฐ์ํ ๋๋ง๋ค ํธ์ถ๋ฉ๋๋ค. ์ด๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ๊ฑฐ๋, ์ฌ์ฉ์์๊ฒ ์ ์ญ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๊ฑฐ๋, ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๋ค๋ฅธ ์กฐ์น๋ฅผ ์ทจํ ์ ์์ต๋๋ค.
์ค์: window.onerror
์ด๋ฒคํธ ํธ๋ค๋ฌ์์ true
๋ฅผ ๋ฐํํ๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ๊ธฐ๋ณธ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ผ๋์ ๋์ด์ผ ํฉ๋๋ค. ๊ธฐ๋ณธ ๋ฉ์์ง๋ฅผ ์ต์ ํ๋ ๊ฒฝ์ฐ, ๋ช
ํํ๊ณ ์ ์ตํ ๋์์ ์ ๊ณตํด์ผ ํฉ๋๋ค.
์ค๋ฅ ๊ฒฝ๊ณ ์ฌ์ฉ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
๋ค์์ ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ฌ์ฉํ ๋ ์ผ๋์ ๋์ด์ผ ํ ๋ช ๊ฐ์ง ๋ชจ๋ฒ ์ฌ๋ก์ ๋๋ค:
- ์ ๋ต์ ์ผ๋ก ์ค๋ฅ ๊ฒฝ๊ณ ๋ฐฐ์น: ์ค๋ฅ๋ฅผ ๊ฒฉ๋ฆฌํ๊ณ ์ฐ์์ ์ผ๋ก ํผ์ง๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์ ์ค๋ฅ ๊ฒฝ๊ณ๋ก ๊ฐ์ธ์ธ์. ์ ์ฒด ๋ผ์ฐํธ๋ UI์ ์ฃผ์ ์น์ ์ ๊ฐ์ธ๋ ๊ฒ์ ๊ณ ๋ คํด๋ณด์ธ์.
- ์ ์ตํ ๋์ฒด UI ์ ๊ณต: ๋์ฒด UI๋ ์ฌ์ฉ์์๊ฒ ์ค๋ฅ๊ฐ ๋ฐ์ํ์์ ์๋ฆฌ๊ณ ์ ์ฌ์ ์ผ๋ก ๋ณต๊ตฌํ ๋ฐฉ๋ฒ์ ์ ๊ณตํด์ผ ํฉ๋๋ค. "๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค."์ ๊ฐ์ ์ผ๋ฐ์ ์ธ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ๊ฒ์ ํผํ์ธ์.
- ์ค๋ฅ ๊ธฐ๋ก:
componentDidCatch
์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ Sentry๋ Bugsnag ๊ฐ์ ์๋น์ค์ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ์ธ์. ์ด๋ ๋ฌธ์ ์ ๊ทผ๋ณธ ์์ธ์ ์ถ์ ํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ์ฑ์ ํฅ์์ํค๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. - ์์๋ ์ค๋ฅ์ ์ค๋ฅ ๊ฒฝ๊ณ ์ฌ์ฉํ์ง ์๊ธฐ: ์ค๋ฅ ๊ฒฝ๊ณ๋ ์๊ธฐ์น ์์ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. ์์๋ ์ค๋ฅ(์: ์ ํจ์ฑ ๊ฒ์ฌ ์ค๋ฅ, API ์ค๋ฅ)์ ๊ฒฝ์ฐ,
try...catch
๋ธ๋ก์ด๋ ์ฌ์ฉ์ ์ ์ ์ค๋ฅ ์ฒ๋ฆฌ ์ปดํฌ๋ํธ์ ๊ฐ์ ๋ ๊ตฌ์ฒด์ ์ธ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ์ธ์. - ์ฌ๋ฌ ์์ค์ ์ค๋ฅ ๊ฒฝ๊ณ ๊ณ ๋ ค: ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ค์ฒฉํ์ฌ ์ฌ๋ฌ ์์ค์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ฒ๋ฆฌ๋์ง ์์ ๋ชจ๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ์ฌ ์ผ๋ฐ์ ์ธ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ์ ์ญ ์ค๋ฅ ๊ฒฝ๊ณ์ ํน์ ์ปดํฌ๋ํธ์ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ์ฌ ๋ ์์ธํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ๋ ๊ตฌ์ฒด์ ์ธ ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค.
- ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ์์ง ๋ง์ธ์: ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ์๋ฒ์์๋ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค. ์ค๋ฅ ๊ฒฝ๊ณ๋ ์๋ฒ์์๋ ์๋ํ์ง๋ง, ์ด๊ธฐ ๋ ๋๋ง ์ค์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ธฐ ์ํด ์ถ๊ฐ์ ์ธ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํด์ผ ํ ์๋ ์์ต๋๋ค.
๊ณ ๊ธ ์ค๋ฅ ๊ฒฝ๊ณ ๊ธฐ๋ฒ
1. ๋ ๋ ํ๋กญ(Render Prop) ์ฌ์ฉํ๊ธฐ
์ ์ ์ธ ๋์ฒด UI๋ฅผ ๋ ๋๋งํ๋ ๋์ , ๋ ๋ ํ๋กญ์ ์ฌ์ฉํ์ฌ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐฉ์์ ๋ ์ ์ฐํ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. ๋ ๋ ํ๋กญ์ ์ปดํฌ๋ํธ๊ฐ ๋ฌด์ธ๊ฐ๋ฅผ ๋ ๋๋งํ๋ ๋ฐ ์ฌ์ฉํ๋ ํจ์ํ prop์ ๋๋ค.
class ErrorBoundary extends React.Component {
// ... (์ด์ ๊ณผ ๋์ผ)
render() {
if (this.state.hasError) {
// ๋ ๋ ํ๋กญ์ ์ฌ์ฉํ์ฌ ๋์ฒด UI ๋ ๋๋ง
return this.props.fallbackRender(this.state.error, this.state.errorInfo);
}
return this.props.children;
}
}
function App() {
return (
<ErrorBoundary fallbackRender={(error, errorInfo) => (
<div>
<h2>๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค!</h2>
<p>์ค๋ฅ: {error.message}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{errorInfo.componentStack}
</details>
</div>
)}>
<MyComponentThatMightThrow/>
</ErrorBoundary>
);
}
์ด๋ฅผ ํตํด ์ค๋ฅ ๊ฒฝ๊ณ๋ณ๋ก ๋์ฒด UI๋ฅผ ๋ง์ถค ์ค์ ํ ์ ์์ต๋๋ค. fallbackRender
prop์ ์ค๋ฅ ๋ฐ ์ค๋ฅ ์ ๋ณด๋ฅผ ์ธ์๋ก ๋ฐ์, ์ค๋ฅ์ ๋ฐ๋ผ ๋ ๊ตฌ์ฒด์ ์ธ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๊ฑฐ๋ ๋ค๋ฅธ ์กฐ์น๋ฅผ ์ทจํ ์ ์๊ฒ ํด์ค๋๋ค.
2. ๊ณ ์ฐจ ์ปดํฌ๋ํธ(HOC)๋ก์์ ์ค๋ฅ ๊ฒฝ๊ณ
๋ค๋ฅธ ์ปดํฌ๋ํธ๋ฅผ ์ค๋ฅ ๊ฒฝ๊ณ๋ก ๊ฐ์ธ๋ ๊ณ ์ฐจ ์ปดํฌ๋ํธ(HOC)๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ ๋์ผํ ์ฝ๋๋ฅผ ๋ฐ๋ณตํ์ง ์๊ณ ์ฌ๋ฌ ์ปดํฌ๋ํธ์ ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ ์ฉํ๋ ๋ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
function withErrorBoundary(WrappedComponent) {
return class WithErrorBoundary extends React.Component {
render() {
return (
<ErrorBoundary>
<WrappedComponent {...this.props} />
</ErrorBoundary>
);
}
};
}
// ์ฌ์ฉ๋ฒ:
const MyComponentWithErrorHandling = withErrorBoundary(MyComponentThatMightThrow);
withErrorBoundary
ํจ์๋ ์ปดํฌ๋ํธ๋ฅผ ์ธ์๋ก ๋ฐ์ ์๋ณธ ์ปดํฌ๋ํธ๋ฅผ ์ค๋ฅ ๊ฒฝ๊ณ๋ก ๊ฐ์ธ๋ ์๋ก์ด ์ปดํฌ๋ํธ๋ฅผ ๋ฐํํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์
์ ๋ชจ๋ ์ปดํฌ๋ํธ์ ์ฝ๊ฒ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
์ค๋ฅ ๊ฒฝ๊ณ ํ ์คํธํ๊ธฐ
์ค๋ฅ ๊ฒฝ๊ณ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ํ ์คํธํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Jest๋ React Testing Library์ ๊ฐ์ ํ ์คํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ํ ์คํธํ ์ ์์ต๋๋ค.
๋ค์์ React Testing Library๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ํ ์คํธํ๋ ์์์ ๋๋ค:
import { render, screen, fireEvent } from '@testing-library/react';
import ErrorBoundary from './ErrorBoundary';
function ComponentThatThrows() {
throw new Error('์ด ์ปดํฌ๋ํธ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค');
}
test('์ค๋ฅ๊ฐ ๋ฐ์ํ์ ๋ ๋์ฒด UI๋ฅผ ๋ ๋๋งํฉ๋๋ค', () => {
render(
<ErrorBoundary>
<ComponentThatThrows />
</ErrorBoundary>
);
expect(screen.getByText('๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.')).toBeInTheDocument();
});
์ด ํ
์คํธ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ComponentThatThrows
์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํ
์คํธ๋ ์ค๋ฅ ๊ฒฝ๊ณ์ ์ํด ๋ ๋๋ง๋ ๋์ฒด UI๊ฐ ํ์๋๋์ง ํ์ธํฉ๋๋ค.
์ค๋ฅ ๊ฒฝ๊ณ์ ์๋ฒ ์ปดํฌ๋ํธ (React 18+)
React 18 ์ด์์์ ์๋ฒ ์ปดํฌ๋ํธ๊ฐ ๋์ ๋๋ฉด์, ์ค๋ฅ ๊ฒฝ๊ณ๋ ์ค๋ฅ ์ฒ๋ฆฌ์์ ๊ณ์ํด์ ์ค์ํ ์ญํ ์ ํฉ๋๋ค. ์๋ฒ ์ปดํฌ๋ํธ๋ ์๋ฒ์์ ์คํ๋๊ณ ๋ ๋๋ง๋ ๊ฒฐ๊ณผ๋ฌผ๋ง ํด๋ผ์ด์ธํธ๋ก ๋ณด๋ ๋๋ค. ํต์ฌ ์์น์ ๋์ผํ์ง๋ง, ๊ณ ๋ คํด์ผ ํ ๋ช ๊ฐ์ง ๋ฏธ๋ฌํ ์ฐจ์ด๊ฐ ์์ต๋๋ค:
- ์๋ฒ ์ฌ์ด๋ ์ค๋ฅ ๋ก๊น : ์๋ฒ ์ปดํฌ๋ํธ ๋ด์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ์๋ฒ์์ ๊ธฐ๋กํ๊ณ ์๋์ง ํ์ธํ์ธ์. ์ฌ๊ธฐ์๋ ์๋ฒ ์ฌ์ด๋ ๋ก๊น ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ค๋ฅ ์ถ์ ์๋น์ค๋ก ์ค๋ฅ๋ฅผ ๋ณด๋ด๋ ๊ฒ์ด ํฌํจ๋ ์ ์์ต๋๋ค.
- ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋์ฒด UI: ์๋ฒ ์ปดํฌ๋ํธ๊ฐ ์๋ฒ์์ ๋ ๋๋ง๋๋๋ผ๋, ์ค๋ฅ ๋ฐ์ ์๋ฅผ ๋๋นํ์ฌ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋์ฒด UI๋ฅผ ์ ๊ณตํด์ผ ํฉ๋๋ค. ์ด๋ ์๋ฒ๊ฐ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ์ง ๋ชปํ๋๋ผ๋ ์ฌ์ฉ์๊ฐ ์ผ๊ด๋ ๊ฒฝํ์ ํ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ์คํธ๋ฆฌ๋ฐ SSR: ์คํธ๋ฆฌ๋ฐ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)์ ์ฌ์ฉํ ๋ ์คํธ๋ฆฌ๋ฐ ๊ณผ์ ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ค๋ฅ ๊ฒฝ๊ณ๋ ์ํฅ์ ๋ฐ๋ ์คํธ๋ฆผ์ ๋ํ ๋์ฒด UI๋ฅผ ๋ ๋๋งํ์ฌ ์ด๋ฌํ ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
์๋ฒ ์ปดํฌ๋ํธ์ ์ค๋ฅ ์ฒ๋ฆฌ๋ ๊ณ์ ๋ฐ์ ํ๋ ๋ถ์ผ์ด๋ฏ๋ก, ์ต์ ๋ชจ๋ฒ ์ฌ๋ก์ ๊ถ์ฅ ์ฌํญ์ ์ต์ ์ํ๋ก ์ ์งํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
ํผํด์ผ ํ ์ผ๋ฐ์ ์ธ ํจ์
- ์ค๋ฅ ๊ฒฝ๊ณ์ ๋ํ ๊ณผ๋ํ ์์กด: ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ปดํฌ๋ํธ ๋ด์ ์ ์ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๋์ฒดํ๋ ์๋จ์ผ๋ก ์ฌ์ฉํ์ง ๋ง์ธ์. ํญ์ ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒฌ๊ณ ํ๊ณ ์ ๋ขฐํ ์ ์๋ ์ฝ๋๋ฅผ ์์ฑํ๋๋ก ๋ ธ๋ ฅํ์ธ์.
- ์ค๋ฅ ๋ฌด์ํ๊ธฐ: ์ค๋ฅ ๊ฒฝ๊ณ์ ์ํด ํฌ์ฐฉ๋ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ์ฌ ๋ฌธ์ ์ ๊ทผ๋ณธ ์์ธ์ ์ถ์ ํ ์ ์๋๋ก ํ์ธ์. ๋จ์ํ ๋์ฒด UI๋ฅผ ํ์ํ๊ณ ์ค๋ฅ๋ฅผ ๋ฌด์ํ์ง ๋ง์ธ์.
- ์ ํจ์ฑ ๊ฒ์ฌ ์ค๋ฅ์ ์ค๋ฅ ๊ฒฝ๊ณ ์ฌ์ฉํ๊ธฐ: ์ค๋ฅ ๊ฒฝ๊ณ๋ ์ ํจ์ฑ ๊ฒ์ฌ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ ํฉํ ๋๊ตฌ๊ฐ ์๋๋๋ค. ๋์ ๋ ๊ตฌ์ฒด์ ์ธ ์ ํจ์ฑ ๊ฒ์ฌ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ธ์.
- ์ค๋ฅ ๊ฒฝ๊ณ ํ ์คํธํ์ง ์๊ธฐ: ์ค๋ฅ ๊ฒฝ๊ณ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ํ ์คํธํ์ธ์.
๊ฒฐ๋ก
์ค๋ฅ ๊ฒฝ๊ณ๋ ๊ฒฌ๊ณ ํ๊ณ ์ ๋ขฐํ ์ ์๋ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ตฌํํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ดํดํจ์ผ๋ก์จ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ถฉ๋์ ๋ฐฉ์งํ๋ฉฐ, ๋๋ฒ๊น ์ ๋จ์ํํ ์ ์์ต๋๋ค. ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ ๋ต์ ์ผ๋ก ๋ฐฐ์นํ๊ณ , ์ ์ตํ ๋์ฒด UI๋ฅผ ์ ๊ณตํ๋ฉฐ, ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ๊ณ , ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ์ฒ ์ ํ ํ ์คํธํ๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์.
์ด ๊ฐ์ด๋์์ ์ค๋ช ํ ์ง์นจ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๋ฉด, React ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ค๋ฅ์ ๋ํด ๋ณต์๋ ฅ์ ๊ฐ์ถ๊ณ ์ฌ์ฉ์์๊ฒ ๊ธ์ ์ ์ธ ๊ฒฝํ์ ์ ๊ณตํ๋๋ก ํ ์ ์์ต๋๋ค.