Reactã®åæå®è¡ã¢ãŒããšãšã©ãŒåŠçæŠç¥ãæ¢æ±ããå ç¢ã§äœ¿ããããã¢ããªã±ãŒã·ã§ã³ãäœæããŸãããšã©ãŒãé©åã«ç®¡çããã·ãŒã ã¬ã¹ãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã確ä¿ããããã®å®è·µçãªãã¯ããã¯ãåŠã³ãŸãããã
Reactã®åæå®è¡ãšã©ãŒåŠçïŒå埩åã®ãããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ã®æ§ç¯
Reactã®åæå®è¡ã¢ãŒãã¯ãå¿çæ§ãé«ãã€ã³ã¿ã©ã¯ãã£ããªãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãäœæããããã®æ°ããå¯èœæ§ãè§£ãæŸã¡ãŸãããããã倧ããªåã«ã¯å€§ããªè²¬ä»»ã䌎ããŸããåæå®è¡ã¢ãŒãã®èŠã§ããéåææäœãšããŒã¿ãã§ããã¯ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæ··ä¹±ãããå¯èœæ§ã®ããé害ç¹ããããããŸãããã®èšäºã§ã¯ãReactã®åæå®è¡ç°å¢å ã§ã®å ç¢ãªãšã©ãŒåŠçæŠç¥ã«ã€ããŠæãäžããäºæãã¬åé¡ãçºçããå Žåã§ããã¢ããªã±ãŒã·ã§ã³ãå埩åãšãŠãŒã¶ãŒãã¬ã³ããªãŒããç¶æã§ããããã«ããŸãã
åæå®è¡ã¢ãŒããšãã®ãšã©ãŒåŠçãžã®åœ±é¿ãçè§£ãã
åŸæ¥ã®Reactã¢ããªã±ãŒã·ã§ã³ã¯åæçã«å®è¡ãããŸããã€ãŸããåæŽæ°ã¯å®äºãããŸã§ã¡ã€ã³ã¹ã¬ããããããã¯ããŸããäžæ¹ãåæå®è¡ã¢ãŒãã§ã¯ãReactã¯ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãåªå ããå¿çæ§ãç¶æããããã«ãæŽæ°ãäžæãäžæåæ¢ããŸãã¯æŸæ£ã§ããŸããããã¯ãã¿ã€ã ã¹ã©ã€ã·ã³ã°ãSuspenseãªã©ã®ææ³ãéããŠå®çŸãããŸãã
ãã ãããã®éåæçãªæ§è³ªã¯ãæ°ãããšã©ãŒã·ããªãªããããããŸããã³ã³ããŒãã³ãã¯ããŸã ãã§ããäžã®ããŒã¿ãã¬ã³ããªã³ã°ããããšããå¯èœæ§ããããŸãããŸãã¯ãéåææäœãäºæãã倱æããå¯èœæ§ããããŸããé©åãªãšã©ãŒåŠçããªããšããããã®åé¡ã¯UIã®ç ŽæããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã®äœäžã«ã€ãªããå¯èœæ§ããããŸãã
Reactã³ã³ããŒãã³ãã«ãããåŸæ¥ã®Try/Catchãããã¯ã®éç
try/catch
ãããã¯ã¯JavaScriptã§ã®ãšã©ãŒåŠçã®åºæ¬ã§ãããReactã³ã³ããŒãã³ãå
ãç¹ã«ã¬ã³ããªã³ã°ã®ã³ã³ããã¹ãã§ã¯å¶éããããŸããã³ã³ããŒãã³ãã®render()
ã¡ãœããå
ã«çŽæ¥é
眮ãããtry/catch
ãããã¯ã¯ãã¬ã³ããªã³ã°èªäœäžã«ã¹ããŒããããšã©ãŒã*ãã£ããããŸãã*ãããã¯ãReactã®ã¬ã³ããªã³ã°ããã»ã¹ãtry/catch
ãããã¯ã®å®è¡ã³ã³ããã¹ãã®ç¯å²å€ã§çºçããããã§ãã
ãã®äŸãèããŠã¿ãŸãããïŒããã¯æåŸ ã©ããã«*åäœããŸãã*ïŒïŒ
function MyComponent() {
try {
// `data`ãundefinedãŸãã¯nullã®å Žåãããã¯ãšã©ãŒãã¹ããŒããŸã
const value = data.property;
return <div>{value}</div>;
} catch (error) {
console.error("ã¬ã³ããªã³ã°äžã®ãšã©ãŒïŒ", error);
return <div>ãšã©ãŒãçºçããŸããïŒ</div>;
}
}
ãã®ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããããšãã«data
ãæªå®çŸ©ã®å Žåãdata.property
ãžã®ã¢ã¯ã»ã¹ã¯ãšã©ãŒãã¹ããŒããŸãããã ããtry/catch
ãããã¯ã¯ãã®ãšã©ãŒã*ãã£ããããŸãã*ããšã©ãŒã¯Reactã³ã³ããŒãã³ãããªãŒãäžã«äŒæããã¢ããªã±ãŒã·ã§ã³å
šäœãã¯ã©ãã·ã¥ããå¯èœæ§ããããŸãã
ãšã©ãŒå¢çã®å°å ¥ïŒReactã®çµã¿èŸŒã¿ãšã©ãŒåŠçã¡ã«ããºã
Reactã¯ãåã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°ãã©ã€ããµã€ã¯ã«ã¡ãœãããããã³ã³ã³ã¹ãã©ã¯ã¿äžã®ãšã©ãŒãåŠçããããã«ç¹å¥ã«èšèšããããšã©ãŒå¢çãšåŒã°ããç¹å¥ãªã³ã³ããŒãã³ããæäŸããŸãããšã©ãŒå¢çã¯å®å šããããšããŠæ©èœãããšã©ãŒãã¢ããªã±ãŒã·ã§ã³å šäœãã¯ã©ãã·ã¥ãããã®ãé²ããé©åãªãã©ãŒã«ããã¯UIãæäŸããŸãã
ãšã©ãŒå¢çã®ä»çµã¿
ãšã©ãŒå¢çã¯ã次ã®ã©ã€ããµã€ã¯ã«ã¡ãœããã®ããããïŒãŸãã¯äž¡æ¹ïŒãå®è£ ããReactã¯ã©ã¹ã³ã³ããŒãã³ãã§ãã
static getDerivedStateFromError(error)
ïŒãã®ã©ã€ããµã€ã¯ã«ã¡ãœããã¯ãåå«ã³ã³ããŒãã³ãã«ãã£ãŠãšã©ãŒãã¹ããŒãããåŸã«åŒã³åºãããŸãããšã©ãŒãåŒæ°ãšããŠåãåãããšã©ãŒãçºçããããšã瀺ãããã«ç¶æ ãæŽæ°ã§ããŸããcomponentDidCatch(error, info)
ïŒãã®ã©ã€ããµã€ã¯ã«ã¡ãœããã¯ãåå«ã³ã³ããŒãã³ãã«ãã£ãŠãšã©ãŒãã¹ããŒãããåŸã«åŒã³åºãããŸãããšã©ãŒãšããšã©ãŒãçºçããã³ã³ããŒãã³ãã¹ã¿ãã¯ã«é¢ããæ å ±ãå«ãinfo
ãªããžã§ã¯ããåãåããŸãããã®ã¡ãœããã¯ããšã©ãŒããã°ã«èšé²ãããããšã©ãŒè¿œè·¡ãµãŒãã¹ïŒSentryãRollbarãBugsnagãªã©ïŒã«ãšã©ãŒãå ±åããããããªã©ãå¯äœçšãå®è¡ããã®ã«æé©ã§ãã
ã·ã³ãã«ãªãšã©ãŒå¢çã®äœæ
ãšã©ãŒå¢çã³ã³ããŒãã³ãã®åºæ¬çãªäŸã次ã«ç€ºããŸãã
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 次ã®ã¬ã³ããªã³ã°ã§ãã©ãŒã«ããã¯UIã衚瀺ããããã«ç¶æ
ãæŽæ°ããŸãã
return { hasError: true };
}
componentDidCatch(error, info) {
// äŸ "componentStack":
// in ComponentThatThrows (created by App)
// in MyErrorBoundary (created by App)
// in div (created by App)
// in App
console.error("ErrorBoundaryã¯ãšã©ãŒããã£ããããŸããïŒ", error, info.componentStack);
// ãšã©ãŒå ±åãµãŒãã¹ã«ãšã©ãŒãèšé²ããããšãã§ããŸã
// logErrorToMyService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
// ã«ã¹ã¿ã ãã©ãŒã«ããã¯UIãã¬ã³ããªã³ã°ã§ããŸã
return <h1>åé¡ãçºçããŸããã</h1>;
}
return this.props.children;
}
}
ãšã©ãŒå¢çã®äœ¿çš
ãšã©ãŒå¢çã䜿çšããã«ã¯ããšã©ãŒãã¹ããŒããå¯èœæ§ã®ããã³ã³ããŒãã³ããåã«ã©ããããŸãã
function MyComponentThatMightError() {
// ãã®ã³ã³ããŒãã³ãã¯ãã¬ã³ããªã³ã°äžã«ãšã©ãŒãã¹ããŒããå¯èœæ§ããããŸã
if (Math.random() < 0.5) {
throw new Error("ã³ã³ããŒãã³ãã倱æããŸããïŒ");
}
return <div>ãã¹ãŠé 調ã§ãïŒ</div>;
}
function App() {
return (
<ErrorBoundary>
<MyComponentThatMightError />
</ErrorBoundary>
);
}
MyComponentThatMightError
ããšã©ãŒãã¹ããŒããå Žåããšã©ãŒå¢çã¯ããããã£ãããããã®ç¶æ
ãæŽæ°ãããã©ãŒã«ããã¯UIïŒãåé¡ãçºçããŸããããïŒãã¬ã³ããªã³ã°ããŸããã¢ããªã±ãŒã·ã§ã³ã®æ®ãã®éšåã¯æ£åžžã«æ©èœãç¶ããŸãã
ãšã©ãŒå¢çã«é¢ããéèŠãªèæ ®äºé
- ç²åºŠïŒãšã©ãŒå¢çãæŠç¥çã«é 眮ããŸããã¢ããªã±ãŒã·ã§ã³å šäœãåäžã®ãšã©ãŒå¢çã§ã©ããããããšã¯é åçãããããŸãããããšã©ãŒãåé¢ããããå ·äœçãªãã©ãŒã«ããã¯UIãæäŸããã«ã¯ãè€æ°ã®ãšã©ãŒå¢çã䜿çšããæ¹ãããããšããããããŸããããšãã°ããŠãŒã¶ãŒãããã¡ã€ã«ã»ã¯ã·ã§ã³ãããŒã¿èŠèŠåã³ã³ããŒãã³ããªã©ãã¢ããªã±ãŒã·ã§ã³ã®ããŸããŸãªã»ã¯ã·ã§ã³ã«å¯ŸããŠå¥ã ã®ã¢ã©ãŒã å¢çãæã€å ŽåããããŸãã
- ãšã©ãŒãã°ïŒ
componentDidCatch
ãå®è£ ããŠããªã¢ãŒããµãŒãã¹ã«ãšã©ãŒãèšé²ããŸããããã«ãããæ¬çªç°å¢ã§ãšã©ãŒã远跡ããæ³šæãå¿ èŠãªã¢ããªã±ãŒã·ã§ã³ã®é åãç¹å®ã§ããŸããSentryãRollbarãBugsnagãªã©ã®ãµãŒãã¹ã¯ããšã©ãŒè¿œè·¡ãšå ±åã®ããã®ããŒã«ãæäŸããŠããŸãã - ãã©ãŒã«ããã¯UIïŒæ å ±ãè±å¯ã§äœ¿ãããããã©ãŒã«ããã¯UIãèšèšããŸããäžè¬çãªãšã©ãŒã¡ãã»ãŒãžã衚瀺ãã代ããã«ãã³ã³ããã¹ããšãŠãŒã¶ãŒãžã®ã¬ã€ãã³ã¹ãæäŸããŸããããšãã°ãããŒãžã®æŽæ°ããµããŒããžã®é£çµ¡ããŸãã¯å¥ã®æäœã®è©Šè¡ãææ¡ããå ŽåããããŸãã
- ãšã©ãŒå埩ïŒãšã©ãŒå埩ã¡ã«ããºã ã®å®è£ ãæ€èšããŸããããšãã°ããŠãŒã¶ãŒã«å€±æããæäœãå詊è¡ã§ããããã«ãããã¿ã³ãæäŸããå ŽåããããŸãããã ããå詊è¡ããžãã¯ã«é©åãªå®å šå¯Ÿçãå«ãŸããŠããããšã確èªããŠãç¡éã«ãŒããåé¿ããããã«æ³šæããŠãã ããã
- ãšã©ãŒå¢çã¯ãããªãŒå ã®*äž*ã®ã³ã³ããŒãã³ãã®ãšã©ãŒã®ã¿ããã£ããããŸãããšã©ãŒå¢çã¯ãããèªäœå ã®ãšã©ãŒããã£ããããããšã¯ã§ããŸããããšã©ãŒå¢çããšã©ãŒã¡ãã»ãŒãžãã¬ã³ããªã³ã°ããããšããŠå€±æããå Žåããšã©ãŒã¯ããã®äžã«ããæãè¿ããšã©ãŒå¢çã«äŒæããŸãã
Suspenseãšãšã©ãŒå¢çã䜿çšããéåææäœäžã®ãšã©ãŒåŠç
Reactã®Suspenseã³ã³ããŒãã³ãã¯ãããŒã¿ãã§ãããªã©ã®éåææäœãåŠçããããã®å®£èšçãªæ¹æ³ãæäŸããŸããã³ã³ããŒãã³ããããŒã¿åŸ ã¡ã®ããã«ãäžæãïŒã¬ã³ããªã³ã°ãäžæåæ¢ïŒãããšãSuspenseã¯ãã©ãŒã«ããã¯UIã衚瀺ããŸãããšã©ãŒå¢çã¯Suspenseãšçµã¿åãããŠããããã®éåææäœäžã«çºçãããšã©ãŒãåŠçã§ããŸãã
ããŒã¿ãã§ãããžã®Suspenseã®äœ¿çš
Suspenseã䜿çšããã«ã¯ãããããµããŒãããããŒã¿ãã§ããã©ã€ãã©ãªãå¿ èŠã§ãã`react-query`ã`swr`ãªã©ã®ã©ã€ãã©ãªãããã³`fetch`ãSuspenseäºæã€ã³ã¿ãŒãã§ãŒã¹ã§ã©ããããã«ã¹ã¿ã ãœãªã¥ãŒã·ã§ã³ã¯ããããå®çŸã§ããŸãã
Promiseãè¿ããSuspenseãšäºææ§ã®ããä»®ã®fetchData
颿°ã䜿çšããç°¡åãªäŸã次ã«ç€ºããŸãã
import React, { Suspense } from 'react';
// SuspenseããµããŒãããä»®ã®fetchData颿°
const fetchData = (url) => {
// ... ïŒããŒã¿ããŸã å©çšã§ããªãå Žåã«Promiseãã¹ããŒããå®è£
ïŒ
};
const Resource = {
data: fetchData('/api/data')
};
function MyComponent() {
const data = Resource.data.read(); // ããŒã¿ãæºåã§ããŠããªãå Žåã¯Promiseãã¹ããŒããŸã
return <div>{data.value}</div>;
}
function App() {
return (
<ErrorBoundary>
<Suspense fallback={<div>èªã¿èŸŒã¿äž...</div>}>
<MyComponent />
</Suspense>
</ErrorBoundary>
);
}
ãã®äŸã§ã¯ã
fetchData
ã¯ãAPIãšã³ããã€ã³ãããããŒã¿ããã§ãããã颿°ã§ããããŒã¿ããŸã å©çšã§ããªãå Žåã«Promiseãã¹ããŒããããã«èšèšãããŠããŸããããã¯ãSuspenseãæ£ããæ©èœããããã®éµã§ããResource.data.read()
ã¯ãããŒã¿ã®èªã¿åãã詊ã¿ãŸããããŒã¿ããŸã å©çšã§ããªãå ŽåïŒPromiseã解決ãããŠããªãå ŽåïŒãPromiseãã¹ããŒããã³ã³ããŒãã³ããäžæãããŸããSuspense
ã¯ãããŒã¿ããã§ãããããŠããéãfallback
UIïŒ<div>èªã¿èŸŒã¿äž...</div>ïŒã衚瀺ããŸããErrorBoundary
ã¯ãMyComponent
ã®ã¬ã³ããªã³ã°äžãŸãã¯ããŒã¿ãã§ããããã»ã¹äžã«çºçãããšã©ãŒããã£ããããŸããAPIåŒã³åºãã倱æããå Žåããšã©ãŒå¢çã¯ãšã©ãŒããã£ãããããã®ãã©ãŒã«ããã¯UIã衚瀺ããŸãã
ãšã©ãŒå¢çã䜿çšããSuspenseå ã§ã®ãšã©ãŒåŠç
Suspenseã䜿çšããå
ç¢ãªãšã©ãŒåŠçã®éµã¯ãSuspense
ã³ã³ããŒãã³ããErrorBoundary
ã§ã©ããããããšã§ããããã«ãããSuspense
å¢çå
ã§ããŒã¿ãã§ãããŸãã¯ã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°äžã«çºçãããšã©ãŒã確å®ã«ãã£ãããããé©åã«åŠçãããŸãã
fetchData
颿°ã倱æããå ŽåããŸãã¯MyComponent
ããšã©ãŒãã¹ããŒããå Žåããšã©ãŒå¢çã¯ãšã©ãŒããã£ãããããã®ãã©ãŒã«ããã¯UIã衚瀺ããŸããããã«ãããã¢ããªã±ãŒã·ã§ã³å
šäœãã¯ã©ãã·ã¥ããã®ãé²ãããããŠãŒã¶ãŒãã¬ã³ããªãŒãªãšã¯ã¹ããªãšã³ã¹ãæäŸãããŸãã
ããŸããŸãªåæå®è¡ã¢ãŒãã·ããªãªã«å¯Ÿããç¹å®ã®ãšã©ãŒåŠçæŠç¥
äžè¬çãªåæå®è¡ã¢ãŒãã·ããªãªã«å¯Ÿããç¹å®ã®ãšã©ãŒåŠçæŠç¥ã次ã«ç€ºããŸãã
1. React.lazyã³ã³ããŒãã³ãã®ãšã©ãŒåŠç
React.lazy
ã䜿çšãããšãã³ã³ããŒãã³ããåçã«ã€ã³ããŒãã§ãããããã¢ããªã±ãŒã·ã§ã³ã®åæãã³ãã«ãµã€ãºãåæžãããŸãããã ããåçã€ã³ããŒãæäœã¯ããããã¯ãŒã¯ãå©çšã§ããªãå ŽåããµãŒããŒãããŠã³ããå Žåãªã©ã倱æããå¯èœæ§ããããŸãã
React.lazy
ã䜿çšããŠãããšãã«ãšã©ãŒãåŠçããã«ã¯ãé
å»¶èªã¿èŸŒã¿ãããã³ã³ããŒãã³ããSuspense
ã³ã³ããŒãã³ããšErrorBoundary
ã§ã©ããããŸãã
import React, { Suspense, lazy } from 'react';
const MyLazyComponent = lazy(() => import('./MyComponent'));
function App() {
return (
<ErrorBoundary>
<Suspense fallback={<div>ã³ã³ããŒãã³ããèªã¿èŸŒã¿äž...</div>}>
<MyLazyComponent />
</Suspense>
</ErrorBoundary>
);
}
åçã€ã³ããŒãã倱æããå Žåããšã©ãŒå¢çã¯ãšã©ãŒããã£ãããããã®ãã©ãŒã«ããã¯UIã衚瀺ããŸããSuspenseã³ã³ããŒãã³ãã¯ãReactãã³ã³ããŒãã³ãã®èªã¿èŸŒã¿ã詊ã¿ãŠããéããã³ã³ããŒãã³ããèªã¿èŸŒã¿äž...ãã¡ãã»ãŒãžã衚瀺ããŸãã
2. ããŒã¿å€æŽäžã®ãšã©ãŒåŠç
ããŒã¿å€æŽïŒæŽæ°ãäœæãåé€ãªã©ïŒã«ã¯ãå€ãã®å Žåã倱æããå¯èœæ§ãããéåææäœãå«ãŸããŸããããŒã¿å€æŽãåŠçããå Žåã¯ãæäœã®æåãŸãã¯å€±æã«ã€ããŠãŠãŒã¶ãŒã«ãã£ãŒãããã¯ãæäŸããããšãéèŠã§ãã
ä»®ã®updateData
颿°ã䜿çšããäŸã次ã«ç€ºããŸãã
import React, { useState } from 'react';
function MyComponent() {
const [isUpdating, setIsUpdating] = useState(false);
const [updateError, setUpdateError] = useState(null);
const handleUpdate = async () => {
setIsUpdating(true);
setUpdateError(null);
try {
await updateData(someData);
// æŽæ°æå
console.log("æŽæ°ã«æåããŸããïŒ");
} catch (error) {
// æŽæ°å€±æ
console.error("æŽæ°ã«å€±æããŸããïŒ", error);
setUpdateError(error.message || "æŽæ°äžã«ãšã©ãŒãçºçããŸããã");
} finally {
setIsUpdating(false);
}
};
return (
<div>
<button onClick={handleUpdate} disabled={isUpdating}>
{isUpdating ? 'æŽæ°äž...' : 'æŽæ°'}
</button>
{updateError && <div className="error">ãšã©ãŒïŒ{updateError}</div>}
</div>
);
}
ãã®äŸã§ã¯ã
isUpdating
ç¶æ 倿°ã¯ãæŽæ°æäœãé²è¡äžãã©ããã远跡ããŸããupdateError
ç¶æ 倿°ã¯ãæŽæ°äžã«çºçãããšã©ãŒãæ ŒçŽããŸããhandleUpdate
颿°ã¯ãupdateData
åŒã³åºãäžã«çºçããå¯èœæ§ã®ãããšã©ãŒãåŠçããããã«try/catch
ãããã¯ã䜿çšããŸãã- ã³ã³ããŒãã³ãã¯ãæŽæ°ãé²è¡äžã¯ããŒãã€ã³ãžã±ãŒã¿ãŒã衚瀺ããæŽæ°ã倱æããå Žåã¯ãšã©ãŒã¡ãã»ãŒãžã衚瀺ããŸãã
3. ãµãŒãããŒãã£ã©ã€ãã©ãªã䜿çšãããšã©ãŒåŠç
ãµãŒãããŒãã£ã©ã€ãã©ãªã䜿çšããå Žåãããããã©ã®ããã«ãšã©ãŒãåŠçããReactãšã©ãŒåŠçæŠç¥ã«ã©ã®ããã«çµ±åã§ããããçè§£ããããšãéèŠã§ããå€ãã®ã©ã€ãã©ãªã¯ãã³ãŒã«ããã¯ãPromiseããŸãã¯ã€ãã³ããªã¹ããŒãªã©ãç¬èªã®ãšã©ãŒåŠçã¡ã«ããºã ãæäŸããŠããŸãã
ããšãã°ããã£ãŒãã©ã€ãã©ãªã䜿çšããŠããå Žåããã£ãŒãã®ã¬ã³ããªã³ã°ããã»ã¹äžã«çºçãããšã©ãŒãåŠçããå¿ èŠãããå ŽåããããŸããã©ã€ãã©ãªã®ãšã©ãŒåŠçã¡ã«ããºã ã䜿çšããŠããããã®ãšã©ãŒããã£ãããããã©ãŒã«ããã¯UIã衚瀺ãããããšã©ãŒããªã¢ãŒããµãŒãã¹ã«ãã°ã«èšé²ãããã§ããŸãããµãŒãããŒãã£ã©ã€ãã©ãªã®æšå¥šããããšã©ãŒåŠçæé ã«ã€ããŠã¯ãåžžã«ã©ã€ãã©ãªã®ããã¥ã¡ã³ããåç §ããŠãã ããã
Reactåæå®è¡ãšã©ãŒåŠçã®ãã¹ããã©ã¯ãã£ã¹
Reactã¢ããªã±ãŒã·ã§ã³ã§ãšã©ãŒåŠçãå®è£ ããéã«çæãã¹ããã¹ããã©ã¯ãã£ã¹ã次ã«ç€ºããŸãã
- ç©æ¥µçã«ãªããŸãããïŒãšã©ãŒãçºçãããŸã§ãšã©ãŒåŠçã«ã€ããŠèããªãã§ãã ãããæåãããšã©ãŒåŠçã念é ã«çœ®ããŠã¢ããªã±ãŒã·ã§ã³ãèšèšããŸãã
- æç¢ºãªãã£ãŒãããã¯ãæäŸããŠãã ããïŒãšã©ãŒãæç¢ºãã€ç°¡æœãªæ¹æ³ã§ãŠãŒã¶ãŒã«éç¥ããŸããçè§£ã§ããªãé£è§£ãªãšã©ãŒã¡ãã»ãŒãžã®è¡šç€ºã¯é¿ããŠãã ããããšã©ãŒã解決ããæ¹æ³ã«é¢ããã¬ã€ãã³ã¹ãæäŸããŸãã
- ãšã©ãŒããã°ã«èšé²ããïŒè¿œè·¡ãšåæã®ããã«ããªã¢ãŒããµãŒãã¹ã«ãšã©ãŒããã°ã«èšé²ããŸããããã«ãããã¢ããªã±ãŒã·ã§ã³ã®åé¡ãç¹å®ããŠä¿®æ£ããã®ã«åœ¹ç«ã¡ãŸãã
- ãšã©ãŒåŠçããã¹ãããïŒãšã©ãŒåŠçã³ãŒãã培åºçã«ãã¹ãããŠãæåŸ ã©ããã«æ©èœããããšã確èªããŸããããŸããŸãªãšã©ãŒã·ããªãªãã·ãã¥ã¬ãŒãããŠãã¢ããªã±ãŒã·ã§ã³ãããããé©åã«åŠçã§ããããšã確èªããŸãã
- ã¢ããªã±ãŒã·ã§ã³ãç£èŠããïŒæ¬çªç°å¢ã§ã¢ããªã±ãŒã·ã§ã³ãç£èŠããŠãçºçããå¯èœæ§ã®ããæ°ãããšã©ãŒãç¹å®ããŠå¯ŸåŠããŸãã
- ã¢ã¯ã»ã·ããªãã£ãèæ ®ããïŒãšã©ãŒã¡ãã»ãŒãžãé害ã®ãããŠãŒã¶ãŒã§ãã¢ã¯ã»ã¹ã§ããããšã確èªããŸããARIA屿§ã䜿çšããŠã远å ã®ã³ã³ããã¹ããšæ å ±ãæäŸããŸãã
- é床ã«åŠçããªãã§ãã ããïŒäžå¿ èŠã«ãšã©ãŒããã£ããããããšã¯é¿ããŠãã ãããæå³ã®ããæ¹æ³ã§åŠçã§ãããšã©ãŒã®ã¿ããã£ããããŸããä»ã®ãšã©ãŒã¯ãäžäœã¬ãã«ã®ãšã©ãŒå¢çã§åŠçãããããã«ã³ã³ããŒãã³ãããªãŒãäžã«äŒæãããŸãã
é«åºŠãªãšã©ãŒåŠçãã¯ããã¯
1. ã«ã¹ã¿ã ãšã©ãŒå ±åãµãŒãã¹
SentryãRollbarãªã©ã®ãµãŒãã¹ã¯ãšã©ãŒè¿œè·¡ã«åªããŠããŸãããã«ã¹ã¿ã ãšã©ãŒå ±åãµãŒãã¹ãæ§ç¯ããå¿ èŠãããç¹å®ã®èŠä»¶ãããå ŽåããããŸããããã«ã¯ãå éšãã®ã³ã°ã·ã¹ãã ãšã®çµ±åããç¹å®ã®ã»ãã¥ãªãã£ããªã·ãŒã®éµå®ãå«ãŸããå ŽåããããŸãã
ã«ã¹ã¿ã ãšã©ãŒå ±åãµãŒãã¹ãæ§ç¯ããå Žåã¯ã以äžãæ€èšããŠãã ããã
- ããŒã¿åéïŒãšã©ãŒã¡ãã»ãŒãžãã¹ã¿ãã¯ãã¬ãŒã¹ãã³ã³ããŒãã³ãã¹ã¿ãã¯ããŠãŒã¶ãŒæ å ±ããã©ãŠã¶ã®è©³çްãªã©ããšã©ãŒã«é¢ããé¢é£æ å ±ãåéããŸãã
- ããŒã¿åŠçïŒæ©å¯æ å ±ãåé€ããã¹ãã¬ãŒãžãšåæçšã«ãã©ãŒãããããããã«ããšã©ãŒããŒã¿ãåŠçããŸãã
- ããŒã¿ã¹ãã¬ãŒãžïŒãšã©ãŒããŒã¿ãå®å šã§ã¹ã±ãŒã©ãã«ãªããŒã¿ããŒã¹ã«ä¿åããŸãã
- ããŒã¿åæïŒããã·ã¥ããŒããã¬ããŒããã¢ã©ãŒããªã©ããšã©ãŒããŒã¿ãåæããããã®ããŒã«ãæäŸããŸãã
- çµ±åïŒæ¢åã®éçºããã³éçšã¯ãŒã¯ãããŒã«ãšã©ãŒå ±åãµãŒãã¹ãçµ±åããŸãã
2. ãµãŒããããã¬ãŒã«ãŒãã¿ãŒã³
ãµãŒããããã¬ãŒã«ãŒãã¿ãŒã³ã¯ãã¢ããªã±ãŒã·ã§ã³ã倱æããå¯èœæ§ã®ããæäœãç¹°ãè¿ãå®è¡ããããšããã®ãé²ãããã«äœ¿çšããããœãããŠã§ã¢èšèšãã¿ãŒã³ã§ããä¿¡é Œæ§ã®äœãå€éšãµãŒãã¹ãšã®å¯Ÿè©±ã«ç¹ã«åœ¹ç«ã¡ãŸãã
Reactã®ã³ã³ããã¹ãã§ã¯ããµãŒããããã¬ãŒã«ãŒãã¿ãŒã³ãå®è£ ããŠãã³ã³ããŒãã³ãã倱æããAPIãšã³ããã€ã³ãããããŒã¿ãç¹°ãè¿ããã§ããããããšããã®ãé²ãããšãã§ããŸãããµãŒããããã¬ãŒã«ãŒã¯ã髿¬¡ã³ã³ããŒãã³ããŸãã¯ã«ã¹ã¿ã ããã¯ãšããŠå®è£ ã§ããŸãã
ãµãŒããããã¬ãŒã«ãŒã¯éåžžã3ã€ã®ç¶æ ããããŸãã
- éããïŒæäœã¯éåžžã©ããå®è¡ãããŸããæäœã倱æããå ŽåããµãŒããããã¬ãŒã«ãŒã¯ãªãŒãã³ç¶æ ã«é·ç§»ããŸãã
- éãïŒæäœã¯å®è¡ãããŸããã代ããã«ããã©ãŒã«ããã¯UIã衚瀺ãããŸããäžå®æéåŸããµãŒããããã¬ãŒã«ãŒã¯åéç¶æ ã«é·ç§»ããŸãã
- åéïŒæäœã¯éãããåæ°ã ãå®è¡ã§ããŸããæäœãæåããå ŽåããµãŒããããã¬ãŒã«ãŒã¯éããç¶æ ã«é·ç§»ããŸããæäœã倱æããå ŽåããµãŒããããã¬ãŒã«ãŒã¯ãªãŒãã³ç¶æ ã«æ»ããŸãã
3. `useErrorBoundary`ã«ã¹ã¿ã ããã¯ã®äœ¿çš
颿°ã³ã³ããŒãã³ãã®å Žåãåã€ã³ã¹ã¿ã³ã¹ã«å°çšã®ãšã©ãŒå¢çã³ã³ããŒãã³ããäœæãããšåé·ã«æããããå ŽåããããŸãããšã©ãŒåŠçããžãã¯ã`useErrorBoundary`ãšåŒã°ããã«ã¹ã¿ã ããã¯å ã«ã«ãã»ã«åã§ããŸãã
import { useState, useCallback } from 'react';
function useErrorBoundary() {
const [error, setError] = useState(null);
const resetError = useCallback(() => {
setError(null);
}, []);
const captureError = useCallback((e) => {
setError(e);
}, []);
return {
error,
captureError,
resetError,
};
}
export default useErrorBoundary;
ããã§ããã®ããã¯ã颿°ã³ã³ããŒãã³ãã§äœ¿çšã§ããŸãã
import useErrorBoundary from './useErrorBoundary';
function MyComponent() {
const { error, captureError, resetError } = useErrorBoundary();
if (error) {
return (
<div>
<h1>åé¡ãçºçããŸããïŒ</h1>
<p>{error.message}</p>
<button onClick={resetError}>ããäžåºŠã詊ããã ãã</button>
</div>
);
}
try {
// ãšã©ãŒãã¹ããŒããå¯èœæ§ã®ããã³ã³ããŒãã³ãããžãã¯
const result = performDangerousOperation();
return <div>{result}</div>;
} catch (e) {
captureError(e);
return null; // ãŸãã¯ãã®ä»ã®ãã©ãŒã«ããã¯
}
}
ãã®ãã¿ãŒã³ã¯ãåå©çšå¯èœãªããã¯å ã«ç¶æ ãšããžãã¯ãã«ãã»ã«åããããšã«ããã颿°ã³ã³ããŒãã³ãå ã®ãšã©ãŒåŠçãç°¡çŽ åããŸãã
çµè«
ãšã©ãŒåŠçã¯ãç¹ã«åæå®è¡ã¢ãŒãã®ã³ã³ããã¹ãã§ãå
ç¢ã§äœ¿ããããReactã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®éèŠãªåŽé¢ã§ããåŸæ¥ã®try/catch
ãããã¯ã®å¶éãçè§£ãããšã©ãŒå¢çãšSuspenseãæŽ»çšãããã¹ããã©ã¯ãã£ã¹ã«åŸãããšã§ããšã©ãŒã«å¯ŸããŠå埩åããããã·ãŒã ã¬ã¹ãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸããã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸããã¢ããªã±ãŒã·ã§ã³ã®å
·äœçãªããŒãºã«åãããŠãšã©ãŒåŠçæŠç¥ã調æŽããæ¬çªç°å¢ã§ã¢ããªã±ãŒã·ã§ã³ãç¶ç¶çã«ç£èŠããŠãçºçããå¯èœæ§ã®ããæ°ãããšã©ãŒãç¹å®ããŠå¯ŸåŠããããšãå¿ããªãã§ãã ãããå
æ¬çãªãšã©ãŒåŠçã«æè³ããããšã§ãReactã¢ããªã±ãŒã·ã§ã³ãä¿¡é Œæ§ãé«ããä¿å®å¯èœã§ãäžçäžã®ãŠãŒã¶ãŒã«ãšã£ãŠäœ¿ãããããã®ã«ãªãããšãä¿èšŒã§ããŸãã倿§ãªããã¯ã°ã©ãŠã³ããæã€ãŠãŒã¶ãŒã«ãšã£ãŠåœ¹ç«ã€ãæç¢ºã§ãããããããšã©ãŒã¡ãã»ãŒãžã®éèŠæ§ãå¿ããªãã§ãã ããããšã©ãŒåŠçèšèšããã»ã¹äžã«åœéåãšããŒã«ã©ã€ãºãèæ
®ããããšã§ãã¢ããªã±ãŒã·ã§ã³ã¯ã°ããŒãã«ãªèŠèŽè
ã«ãšã£ãŠããå
æ¬çã§å¹æçã«ãªããŸãã