Hi everyone, I'm Kasong.
This article will explain the complete implementation logic of React
in Error Boundaries
A picture summarizes:
Here is a brief explanation of the React
workflow, which will be useful later. It is divided into three steps:
- Trigger
update
stage: Calculate the side effects
caused by the 161a9b978b7e17 update
- commit stage: execute
side effects in the host environment
There are many side effects , such as:
- Insert
DOM
node - Execute
useEffect
callback
Okay, let's get into the topic.
Welcome to join human high-quality front-end framework group , take the flight
What are Error Boundaries
React
provides two related error handling API
:
getDerivedStateFromError
: Static method, which provides an opportunity to renderfallback UI
componentDidCatch
: Component instance method, which provides an opportunity to record error information when an error occurs
Use these two API
of ClassComponent
often referred to Error Boundaries
(boundary error).
In Error Boundaries
of sons components all occurred in the within React workflow errors will be Error Boundaries
capture.
Through the introduction at the beginning, we can know that the React workflow refers to:
- render stage
- commit phase
Consider the following code:
class ErrorBoundary extends Component {
componentDidCatch(e) {
console.warn(“发生错误”, e);
}
render() {
return <div>{this.props.children}</div>;
}
}
const App = () => (
<ErrorBoundary>
<A><B/></A>
<C/>
<ErrorBoundary>
)
A
, B
, C
as ErrorBoundary
descendants assembly occurs when the workflow React errors, will be ErrorBoundary
in componentDidCatch
capture method.
Step 1: catch the error
First look at when the errors in the when they are caught.
render
stage is as follows, and errors that occur will be handled handleError
do {
try {
// 对于并发更新则是workLoopConcurrent
workLoopSync();
break;
} catch (thrownValue) {
handleError(root, thrownValue);
}
} while (true);
commit
stage contains a lot of work, such as:
componentDidMount/Update
execution- Bind/
ref
useEffect/useLayoutEffect
callback
anddestroy
execution
These tasks will be executed in the following form, and the errors that occur will be handled captureCommitPhaseError
try {
// …执行某项工作
} catch (error) {
captureCommitPhaseError(fiber, fiber.return, error);
}
Step 2: construct a callback
It can be found that even if there is no Error Boundaries
, the error in the workflow has been caught React
The correct logic should be:
- If
Error Boundaries
exists, execute correspondingAPI
- Throw out the
React
Error Boundaries
does not exist, throw uncaught error
Therefore, whether it is handleError
or captureCommitPhaseError
, it will start from the parent node of the node where the error occurred, and traverse up layer by layer, looking for the nearest Error Boundaries
.
Once found, it will construct:
- For execution Boundaries API Error of
callback
- For throw React message of
callback
// ...为了可读性,逻辑有删减
function createClassErrorUpdate() {
if (typeof getDerivedStateFromError === 'function') {
// 用于执行getDerivedStateFromError的callback
update.payload = () => {
return getDerivedStateFromError(error);
};
// 用于抛出React提示信息的callback
update.callback = () => {
logCapturedError(fiber, errorInfo);
};
}
if (inst !== null && typeof inst.componentDidCatch === 'function') {
// 用于执行componentDidCatch的callback
update.callback = function callback() {
this.componentDidCatch(error);
};
}
return update;
}
Error Boundaries
is not found, continue to traverse up to the root node.
This will construct:
- For throw uncaught error of
callback
- For throw React message of
callback
// ...为了可读性,逻辑有删减
funffction createRootErrorUpdate() {
// 用于抛出“未捕获的错误”及“React的提示信息”的callback
update.callback = () => {
onUncaughtError(error);
logCapturedError(fiber, errorInfo);
};
return update;
}
Execute callback
When will the constructed callback
be executed?
In React
two in execute user-defined callback of API
:
- For
ClassComponent
,this.setState(newState, callback)
andcallback
parameters innewState
can be passedFunction
ascallback
Therefore, for Error Boundaries
, it is equivalent to actively triggering an update:
this.setState(() => {
// 用于执行getDerivedStateFromError的callback
}, () => {
// 用于执行componentDidCatch的callback
// 以及 用于抛出React提示信息的callback
})
- For the root node, execute
ReactDOM.render(element, container, callback)
parameter incallback
to passFunction
ascallback
Therefore, for without Error Boundaries , it is equivalent to actively executing the following functions:
ReactDOM.render(element, container, () => {
// 用于抛出“未捕获的错误”及“React的提示信息”的callback
})
Therefore, Error Boundaries
can be regarded as: React
utilizes the new functions realized by API
Summarize
People often ask: Why is Hooks
not Error Boundaries
?
You can see, Error Boundaries
achieved by means of a this.setState
can pass callback
characteristics, useState
temporarily unable to complete benchmarking.
Finally, you leave a job, in official document describes four cases of error will not be Error Boundaries
captured.
Using the knowledge of this article, can you analyze why they were not captured?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。