@samitouri / QOS-React / commits / 17a966651c

Added suspense to TODO list and added interactions to 'Commit Info' panel

Brian Vaughn committed Mar 20, 2019 at 09:39 UTC 17a966651cc1ee92ece83b71f4671133f2a830ce
8 files changed +109 -56
package.json
+4 -3
@@ -93,13 +93,14 @@
93 "opener": "^1.5.1",
94 "prettier": "^1.16.1",
95 "prop-types": "^15.6.2",
96 - "react": "^16.8",
96 + "react": "^16.8.4",
97 "react-color": "^2.11.7",
98 - "react-dom": "^16.8",
99 - "react-is": "^16.8",
98 + "react-dom": "^16.8.4",
99 + "react-is": "^16.8.4",
100 "react-portal": "^3.1.0",
101 "react-virtualized-auto-sizer": "^1.0.2",
102 "react-window": "^1.5.1",
103 + "scheduler": "^0.13",
104 "semver": "^5.5.1",
105 "style-loader": "^0.23.1",
106 "web-ext": "^1.10.1",
shells/dev/app/ToDoList/List.js
+28 -21
@@ -1,6 +1,7 @@
1 // @flow
2
3 import React, { Fragment, useCallback, useState } from 'react';
4 +import { unstable_trace as trace } from 'scheduler/tracing';
5 import ListItem from './ListItem';
6 import styles from './List.css';
7
@@ -23,16 +24,18 @@ export default function List(props: Props) {
24
25 const handleClick = useCallback(() => {
26 if (newItemText !== '') {
26 - setItems([
27 - ...items,
28 - {
29 - id: uid,
30 - isComplete: false,
31 - text: newItemText,
32 - },
33 - ]);
34 - setUID(uid + 1);
35 - setNewItemText('');
27 + trace(`Add "${newItemText}"`, performance.now(), () => {
28 + setItems([
29 + ...items,
30 + {
31 + id: uid,
32 + isComplete: false,
33 + text: newItemText,
34 + },
35 + ]);
36 + setUID(uid + 1);
37 + setNewItemText('');
38 + });
39 }
40 }, [newItemText, items, uid]);
41
@@ -54,24 +57,28 @@ export default function List(props: Props) {
57
58 const removeItem = useCallback(
59 itemToRemove => {
57 - setItems(items.filter(item => item !== itemToRemove));
60 + trace(`Remove "${itemToRemove.text}"`, performance.now(), () => {
61 + setItems(items.filter(item => item !== itemToRemove));
62 + });
63 },
64 [items]
65 );
66
67 const toggleItem = useCallback(
68 itemToToggle => {
64 - const index = items.indexOf(itemToToggle);
69 + trace(`Toggle "${itemToToggle.text}"`, performance.now(), () => {
70 + const index = items.indexOf(itemToToggle);
71
66 - setItems(
67 - items
68 - .slice(0, index)
69 - .concat({
70 - ...itemToToggle,
71 - isComplete: !itemToToggle.isComplete,
72 - })
73 - .concat(items.slice(index + 1))
74 - );
72 + setItems(
73 + items
74 + .slice(0, index)
75 + .concat({
76 + ...itemToToggle,
77 + isComplete: !itemToToggle.isComplete,
78 + })
79 + .concat(items.slice(index + 1))
80 + );
81 + });
82 },
83 [items]
84 );
shells/dev/app/ToDoList/ListItem.js
+4 -2
@@ -1,6 +1,6 @@
1 // @flow
2
3 -import React, { useCallback } from 'react';
3 +import React, { memo, useCallback } from 'react';
4 import styles from './ListItem.css';
5
6 import type { Item } from './List';
@@ -11,7 +11,7 @@ type Props = {|
11 toggleItem: (item: Item) => void,
12 |};
13
14 -export default function ListItem({ item, removeItem, toggleItem }: Props) {
14 +function ListItem({ item, removeItem, toggleItem }: Props) {
15 const handleDelete = useCallback(() => {
16 removeItem(item);
17 }, [item, removeItem]);
@@ -37,3 +37,5 @@ export default function ListItem({ item, removeItem, toggleItem }: Props) {
37 </li>
38 );
39 }
40 +
41 +export default memo<Props>(ListItem);
src/devtools/cache.js
+18 -3
@@ -1,6 +1,6 @@
1 // @flow
2
3 -import { createContext, useContext } from 'react';
3 +import React, { createContext } from 'react';
4
5 // Cache implementation was forked from the React repo:
6 // https://github.com/facebook/react/blob/master/packages/react-cache/src/ReactCache.js
@@ -46,6 +46,21 @@ const Pending = 0;
46 const Resolved = 1;
47 const Rejected = 2;
48
49 +const ReactCurrentDispatcher = (React: any)
50 + .__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher;
51 +
52 +function readContext(Context, observedBits) {
53 + const dispatcher = ReactCurrentDispatcher.current;
54 + if (dispatcher === null) {
55 + throw new Error(
56 + 'react-cache: read and preload may only be called from within a ' +
57 + "component's render. They are not supported in event handlers or " +
58 + 'lifecycle methods.'
59 + );
60 + }
61 + return dispatcher.readContext(Context, observedBits);
62 +}
63 +
64 function identityHashFn(input) {
65 return input;
66 }
@@ -106,7 +121,7 @@ export function createResource<I, K: string | number, V>(
121 read(input: I): V {
122 // Prevent access outside of render.
123 // eslint-disable-next-line react-hooks/rules-of-hooks
109 - useContext(CacheContext);
124 + readContext(CacheContext);
125
126 const key = hashInput(input);
127 const result: Result<V> = accessResult(resource, fetch, input, key);
@@ -132,7 +147,7 @@ export function createResource<I, K: string | number, V>(
147 preload(input: I): void {
148 // Prevent access outside of render.
149 // eslint-disable-next-line react-hooks/rules-of-hooks
135 - useContext(CacheContext);
150 + readContext(CacheContext);
151
152 const key = hashInput(input);
153 accessResult(resource, fetch, input, key);
src/devtools/views/Profiler/SidebarCommitInfo.css
+9 -3
@@ -12,14 +12,20 @@
12 padding: 0.5rem;
13 }
14
15 -.List {
15 +.List,
16 +.InteractionList {
17 list-style: none;
18 margin: 0;
19 padding: 0;
20 }
21
21 -.ListItem {
22 - margin: 0 0 0.25rem;
22 +.InteractionList {
23 + padding: 0.5rem;
24 +}
25 +
26 +.ListItem,
27 +.InteractionListItem {
28 + margin: 0 0 0.5rem;
29 }
30
31 .Label {
src/devtools/views/Profiler/SidebarCommitInfo.js
+24 -9
@@ -15,6 +15,11 @@ export default function SidebarCommitInfo(_: Props) {
15 );
16
17 const { profilingCache } = useContext(StoreContext);
18 +
19 + if (selectedCommitIndex === null) {
20 + return null; // TODO (profiling) Use a better UI
21 + }
22 +
23 const { commitDurations, commitTimes } = profilingCache.ProfilingSummary.read(
24 {
25 rendererID: ((rendererID: any): number),
@@ -22,9 +27,11 @@ export default function SidebarCommitInfo(_: Props) {
27 }
28 );
29
25 - if (selectedCommitIndex === null) {
26 - return 'TODO';
27 - }
30 + const { interactions } = profilingCache.CommitDetails.read({
31 + commitIndex: ((selectedCommitIndex: any): number),
32 + rendererID: ((rendererID: any): number),
33 + rootID: ((rootID: any): number),
34 + });
35
36 return (
37 <Fragment>
@@ -34,21 +41,29 @@ export default function SidebarCommitInfo(_: Props) {
41 <li className={styles.ListItem}>
42 <label className={styles.Label}>Committed at</label>:{' '}
43 <span className={styles.Value}>
37 - {formatTime(commitTimes[selectedCommitIndex])}s
44 + {formatTime(commitTimes[((selectedCommitIndex: any): number)])}s
45 </span>
46 </li>
47 <li className={styles.ListItem}>
48 <label className={styles.Label}>Render duration</label>:{' '}
49 <span className={styles.Value}>
43 - {formatDuration(commitDurations[selectedCommitIndex])}ms
50 + {formatDuration(
51 + commitDurations[((selectedCommitIndex: any): number)]
52 + )}
53 + ms
54 </span>
55 </li>
56 <li className={styles.ListItem}>
57 <label className={styles.Label}>Interactions</label>:
48 - <ul className={styles.List}>
49 - <li className={styles.ListItem}>
50 - <div>Coming soon</div>
51 - </li>
58 + <ul className={styles.InteractionList}>
59 + {interactions.length === 0 ? (
60 + <li className={styles.InteractionListItem}>None</li>
61 + ) : null}
62 + {interactions.map((interaction, index) => (
63 + <li key={index} className={styles.ListItem}>
64 + {interaction.name}
65 + </li>
66 + ))}
67 </ul>
68 </li>
69 </ul>
src/devtools/views/Profiler/SnapshotSelector.js
+2
@@ -12,6 +12,8 @@ import styles from './SnapshotSelector.css';
12
13 export type Props = {||};
14
15 +// TODO (profiling) Left/right arrow navigation.
16 +
17 export default function SnapshotSelector(_: Props) {
18 const {
19 isCommitFilterEnabled,
yarn.lock
+20 -15
@@ -8630,21 +8630,26 @@ react-color@^2.11.7:
8630 reactcss "^1.2.0"
8631 tinycolor2 "^1.4.1"
8632
8633 -react-dom@^16.8:
8634 - version "16.8.3"
8635 - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.3.tgz#ae236029e66210783ac81999d3015dfc475b9c32"
8636 - integrity sha512-ttMem9yJL4/lpItZAQ2NTFAbV7frotHk5DZEHXUOws2rMmrsvh1Na7ThGT0dTzUIl6pqTOi5tYREfL8AEna3lA==
8633 +react-dom@^16.8.4:
8634 + version "16.8.4"
8635 + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.4.tgz#1061a8e01a2b3b0c8160037441c3bf00a0e3bc48"
8636 + integrity sha512-Ob2wK7XG2tUDt7ps7LtLzGYYB6DXMCLj0G5fO6WeEICtT4/HdpOi7W/xLzZnR6RCG1tYza60nMdqtxzA8FaPJQ==
8637 dependencies:
8638 loose-envify "^1.1.0"
8639 object-assign "^4.1.1"
8640 prop-types "^15.6.2"
8641 - scheduler "^0.13.3"
8641 + scheduler "^0.13.4"
8642
8643 -react-is@^16.8, react-is@^16.8.1:
8643 +react-is@^16.8.1:
8644 version "16.8.3"
8645 resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.3.tgz#4ad8b029c2a718fc0cfc746c8d4e1b7221e5387d"
8646 integrity sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA==
8647
8648 +react-is@^16.8.4:
8649 + version "16.8.4"
8650 + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.4.tgz#90f336a68c3a29a096a3d648ab80e87ec61482a2"
8651 + integrity sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==
8652 +
8653 react-portal@^3.1.0:
8654 version "3.2.0"
8655 resolved "https://registry.yarnpkg.com/react-portal/-/react-portal-3.2.0.tgz#4224e19b2b05d5cbe730a7ba0e34ec7585de0043"
@@ -8665,15 +8670,15 @@ react-window@^1.5.1:
8670 "@babel/runtime" "^7.0.0"
8671 memoize-one "^3.1.1"
8672
8668 -react@^16.8:
8669 - version "16.8.3"
8670 - resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9"
8671 - integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA==
8673 +react@^16.8.4:
8674 + version "16.8.4"
8675 + resolved "https://registry.yarnpkg.com/react/-/react-16.8.4.tgz#fdf7bd9ae53f03a9c4cd1a371432c206be1c4768"
8676 + integrity sha512-0GQ6gFXfUH7aZcjGVymlPOASTuSjlQL4ZtVC5YKH+3JL6bBLCVO21DknzmaPlI90LN253ojj02nsapy+j7wIjg==
8677 dependencies:
8678 loose-envify "^1.1.0"
8679 object-assign "^4.1.1"
8680 prop-types "^15.6.2"
8676 - scheduler "^0.13.3"
8681 + scheduler "^0.13.4"
8682
8683 reactcss@^1.2.0:
8684 version "1.2.3"
@@ -9279,10 +9284,10 @@ sax@>=0.6.0, sax@^1.2.4:
9284 resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
9285 integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
9286
9282 -scheduler@^0.13.3:
9283 - version "0.13.3"
9284 - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.3.tgz#bed3c5850f62ea9c716a4d781f9daeb9b2a58896"
9285 - integrity sha512-UxN5QRYWtpR1egNWzJcVLk8jlegxAugswQc984lD3kU7NuobsO37/sRfbpTdBjtnD5TBNFA2Q2oLV5+UmPSmEQ==
9287 +scheduler@^0.13, scheduler@^0.13.4:
9288 + version "0.13.4"
9289 + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.4.tgz#8fef05e7a3580c76c0364d2df5e550e4c9140298"
9290 + integrity sha512-cvSOlRPxOHs5dAhP9yiS/6IDmVAVxmk33f0CtTJRkmUWcb1Us+t7b1wqdzoC0REw2muC9V5f1L/w5R5uKGaepA==
9291 dependencies:
9292 loose-envify "^1.1.0"
9293 object-assign "^4.1.1"