Skip to content

Commit 4324d17

Browse files
sebmarkbageUmeshmalik
authored andcommitted
[Fizz] Reset error component stack and fix error messages (facebook#27456)
The way we collect component stacks right now are pretty fragile. We expect that we'll call captureBoundaryErrorDetailsDev whenever an error happens. That resets lastBoundaryErrorComponentStackDev to null but if we don't, it just lingers and we don't set it to anything new then which leaks the previous component stack into the next time we have an error. So we need to reset it in a bunch of places. This is still broken with erroredReplay because it has the inverse problem that abortRemainingReplayNodes can call captureBoundaryErrorDetailsDev more than one time. So the second boundary won't get a stack. We probably should try to figure out an alternative way to carry along the stack. Perhaps WeakMap keyed by the error object. This also fixes an issue where we weren't invoking the onShellReady event if we error a replay. That event is a bit weird for resuming because we're probably really supposed to just invoke it immediately if we have already flushed the shell in the prerender which is always atm. Right now, it gets invoked later than necessary because you could have a resumed hole ready before a sibling in the shell is ready and that's blocked.
1 parent 6f13243 commit 4324d17

File tree

17 files changed

+637
-401
lines changed

17 files changed

+637
-401
lines changed

fixtures/concurrent/time-slicing/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
npm-debug.log*
2020
yarn-debug.log*
2121
yarn-error.log*
22+
yarn.lock
Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
{
22
"name": "cpu-demo",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"private": true,
55
"dependencies": {
6-
"glamor": "^2.20.40",
76
"react": "0.0.0-experimental-269dd6ec5",
87
"react-dom": "0.0.0-experimental-269dd6ec5",
9-
"react-markdown": "^3.2.0",
10-
"react-scripts": "^1.1.4",
11-
"victory": "^0.25.6"
8+
"react-scripts": "^5.0.1",
9+
"victory": "^36.0.0"
1210
},
1311
"scripts": {
1412
"copy-source": "cp -r ../../../build/oss-experimental/* ./node_modules/",
1513
"dev": "react-scripts start",
1614
"build": "react-scripts build",
1715
"test": "react-scripts test --env=jsdom",
1816
"eject": "react-scripts eject"
17+
},
18+
"browserslist": {
19+
"production": [
20+
">0.2%",
21+
"not dead",
22+
"not op_mini all"
23+
],
24+
"development": [
25+
"last 1 chrome version",
26+
"last 1 firefox version",
27+
"last 1 safari version"
28+
]
1929
}
2030
}

fixtures/concurrent/time-slicing/public/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<meta charset="utf-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
66
<meta name="theme-color" content="#000000">
7+
<meta name="description" content="Shows use of sync, debounce, async computation in react">
78
<!--
89
manifest.json provides metadata used when your web app is added to the
910
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React, { useEffect, useState, useTransition } from "react";
2+
3+
import _map from "lodash/map";
4+
import _debounce from "lodash/debounce";
5+
6+
import { Charts, Clock, Options } from "./components";
7+
8+
import { getStreamData } from "./utils";
9+
import { OPTIONS, INITIAL_STATE, STRATEGY, QUESTION_MARK } from "./constants";
10+
11+
import "./index.css";
12+
13+
let _ignoreClick = null;
14+
15+
const App = () => {
16+
const [showDemo, setShowDemo] = useState(INITIAL_STATE.showDemo);
17+
const [strategy, setStrategy] = useState(INITIAL_STATE.strategy);
18+
const [value, setValue] = useState(INITIAL_STATE.value);
19+
const [showClock, setShowClock] = useState(INITIAL_STATE.showClock);
20+
const [isPending, startTransition] = useTransition();
21+
22+
useEffect(() => {
23+
window.addEventListener("keydown", showClockEventHandler);
24+
return () => {
25+
window.removeEventListener("keydown", showClockEventHandler);
26+
};
27+
}, []);
28+
29+
const showClockEventHandler = (e) => {
30+
if (e.key.toLowerCase() === QUESTION_MARK) {
31+
e.preventDefault();
32+
setShowClock((prev) => !prev);
33+
}
34+
};
35+
36+
const handleChartClick = (e) => {
37+
if (showDemo) {
38+
if (e.shiftKey) {
39+
setShowDemo(false);
40+
}
41+
return;
42+
}
43+
if (strategy !== STRATEGY.ASYNC) {
44+
setShowDemo((prev) => !prev);
45+
return;
46+
}
47+
if (_ignoreClick) {
48+
return;
49+
}
50+
_ignoreClick = true;
51+
52+
startTransition(() => {
53+
setShowDemo(true);
54+
_ignoreClick = false;
55+
});
56+
};
57+
58+
const handleChange = (e) => {
59+
const val = e.target.value;
60+
switch (strategy) {
61+
case STRATEGY.SYNC:
62+
setValue(val);
63+
break;
64+
case STRATEGY.DEBOUNCED:
65+
debouncedHandleChange(val);
66+
break;
67+
case STRATEGY.ASYNC:
68+
startTransition(() => {
69+
setValue(val);
70+
});
71+
break;
72+
default:
73+
break;
74+
}
75+
};
76+
77+
const debouncedHandleChange = _debounce((val) => {
78+
if (strategy === STRATEGY.DEBOUNCED) {
79+
setValue(val);
80+
}
81+
}, 1000);
82+
83+
return (
84+
<div className="container">
85+
<div className="rendering">
86+
{_map(OPTIONS, (option) => (
87+
<Options
88+
{...option}
89+
key={option.strategy}
90+
setStrategy={setStrategy}
91+
currentStrategy={strategy}
92+
/>
93+
))}
94+
</div>
95+
<input
96+
className={"input " + strategy}
97+
id="input"
98+
placeholder="longer input → more components and DOM nodes"
99+
defaultValue={value}
100+
onChange={handleChange}
101+
/>
102+
<div className="demo" onClick={handleChartClick}>
103+
{showDemo && (
104+
<Charts data={getStreamData(value)} isPending={isPending} />
105+
)}
106+
{showClock && <Clock />}
107+
</div>
108+
</div>
109+
);
110+
};
111+
112+
export default App;

fixtures/concurrent/time-slicing/src/Charts.js

Lines changed: 0 additions & 126 deletions
This file was deleted.

fixtures/concurrent/time-slicing/src/Clock.js

Lines changed: 0 additions & 105 deletions
This file was deleted.

0 commit comments

Comments
 (0)