mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Dont count throw as an exit node (React semantics)
React will retry or abort components that throw (depending on a few conditions),
so from React's perspective a `throw` statement is not a normal exit node. Thus
the Rules of Hooks really have a caveat: the set of hooks that are called _in an
execution that returns successfully_ must be consistent. Examples such as the
following are therefore allowed:
```javascript
function Component(props) {
if (props.cond) {
throw new Error(...);
}
useHook();
}
```
By modeling `throw` as an exit node, we rejected cases such as this. This diff
changes to not model throws as exit nodes. #1584 changes this to make it an
option, since some cases will want to consider throw as an exit node.
This commit is contained in:
@@ -113,10 +113,9 @@ class Dominator<T> {
|
||||
*/
|
||||
get(id: T): T | null {
|
||||
const dominator = this.#nodes.get(id);
|
||||
invariant(
|
||||
dominator !== undefined,
|
||||
`Called on invalid node identifier '${id}'`
|
||||
);
|
||||
if (dominator === undefined) {
|
||||
return null;
|
||||
}
|
||||
return dominator === id ? null : dominator;
|
||||
}
|
||||
|
||||
@@ -173,7 +172,7 @@ function computeReverseGraph(fn: HIRFunction): Graph<BlockId> {
|
||||
preds: new Set(eachTerminalSuccessor(block.terminal)),
|
||||
succs: new Set(block.preds),
|
||||
};
|
||||
if (block.terminal.kind === "return" || block.terminal.kind === "throw") {
|
||||
if (block.terminal.kind === "return") {
|
||||
node.preds.add(exitId);
|
||||
exit.succs.add(id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user