Skip to content

Commit 1675422

Browse files
Merge pull request #465 from preactjs/hooks-index
2 parents f78485c + b8a557c commit 1675422

File tree

14 files changed

+151
-26
lines changed

14 files changed

+151
-26
lines changed

src/adapter/10/options.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,6 @@ export function setupOptionsV10(
8585
prevHookName = options._addHookName || options.__a;
8686

8787
o._hook = o.__h = (c: Component, index: number, type: number) => {
88-
const vnode = (c as any)._vnode || (c as any).__v;
89-
const s = getStatefulHooks(vnode);
90-
if (s && Array.isArray(s) && s.length > 0 && getComponent(s[0])) {
91-
s[0]._oldValue = getStatefulHookValue(s);
92-
s[0]._index = index;
93-
}
94-
9588
if (type) {
9689
addHookStack(type);
9790
}
@@ -132,6 +125,19 @@ export function setupOptionsV10(
132125
if (typeof vnode.type === "function") {
133126
const name = getDisplayName(vnode, config);
134127
recordMark(`${name}_diff`);
128+
129+
const c = getComponent(vnode);
130+
const s = getStatefulHooks(vnode);
131+
if (s !== null && c !== null) {
132+
if (!(c as any)._oldHookValues) {
133+
(c as any)._oldHookValues = new Array(s.length).fill(undefined);
134+
}
135+
136+
for (let i = 0; i < s.length; i++) {
137+
const value = getStatefulHookValue(s[i]);
138+
(c as any)._oldHookValues[i] = value;
139+
}
140+
}
135141
}
136142

137143
if (vnode.type !== null) {

src/adapter/10/renderReason.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,20 @@ export function getRenderReasonPost<T extends SharedVNode>(
3030
// Check hooks
3131
const hooks = bindings.getStatefulHooks(next);
3232

33-
if (hooks !== null) {
33+
if (hooks !== null && Array.isArray(c._oldHookValues)) {
34+
const hooksChanged: string[] = [];
3435
for (let i = 0; i < hooks.length; i++) {
3536
if (
3637
bindings.isUseReducerOrState(hooks[i]) &&
37-
hooks[i]._oldValue !== bindings.getStatefulHookValue(hooks[i])
38+
c._oldHookValues[i] !== bindings.getStatefulHookValue(hooks[i])
3839
) {
39-
return createReason(RenderReason.HOOKS_CHANGED, null);
40+
hooksChanged.push(String(i));
4041
}
4142
}
43+
44+
if (hooksChanged.length > 0) {
45+
return createReason(RenderReason.HOOKS_CHANGED, hooksChanged);
46+
}
4247
}
4348

4449
// Check state

src/adapter/protocol/events.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ export function applyOperationsV2(store: Store, data: number[]) {
150150
rendered,
151151
commitRootId,
152152
);
153-
const map = store.profiler.renderReasons.value.set(commitRootId, reasons);
153+
const commitIdx = store.profiler.commits.peek().length - 1;
154+
const map = store.profiler.renderReasons.value.set(commitIdx, reasons);
154155
store.profiler.renderReasons.value = new Map(map);
155156
}
156157

src/adapter/shared/hooks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ export function parseHookData<T extends SharedVNode>(
227227
}
228228
: frame.name,
229229
value,
230+
index: hookIdx,
230231
};
231232
tree.set(id, item);
232233
out.push(item);

src/adapter/shared/renderReasons.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,19 @@ export function renderReasonToStr(reason: RenderReason) {
2626
}
2727
}
2828

29+
// TODO: Track value patch
30+
export type RenderReasonItem = null | string[];
31+
2932
export interface RenderReasonData {
3033
type: RenderReason;
31-
items: string[] | null;
34+
items: RenderReasonItem;
3235
}
3336

3437
export type RenderReasonMap = Map<ID, RenderReasonData | null>;
3538

3639
export function createReason(
3740
type: RenderReason,
38-
items: null | string[],
41+
items: RenderReasonItem,
3942
): RenderReasonData {
4043
return { type, items };
4144
}

src/view/components/Devtools.module.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ p {
114114
--color-props-object: #1b1b1b;
115115
--color-props-null: #1b1b1b;
116116
--color-props-vnode: #1b1b1b;
117+
--color-props-hook-label: #e4e4e4;
117118

118119
/* Profiling */
119120
--color-bystander-text: #333;
@@ -205,6 +206,7 @@ p {
205206
--color-props-object: #dedede;
206207
--color-props-null: #dedede;
207208
--color-props-vnode: #dedede;
209+
--color-props-hook-label: #464646;
208210

209211
/* Profiling */
210212
--color-bystander-text: #d8d8d8;
@@ -242,6 +244,10 @@ p {
242244
--message-warning-link: #8dbff2;
243245
}
244246

247+
:global(.va-middle) {
248+
vertical-align: middle;
249+
}
250+
245251
.switcher {
246252
border-bottom: 0.0625rem solid var(--color-dim-border);
247253
display: flex;

src/view/components/devtools.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66
height: 1rem;
77
}
88

9+
.hook-number {
10+
background: var(--color-props-hook-label);
11+
border-radius: 0.1875rem;
12+
min-width: 1rem;
13+
height: 1rem;
14+
display: inline-flex;
15+
align-items: center;
16+
justify-content: center;
17+
margin-right: 0.125rem;
18+
font-size: 0.6875rem;
19+
}
20+
921
/**
1022
* Sidebar Layout
1123
*/

src/view/components/profiler/components/RenderReasons.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { h } from "preact";
1+
import { h, Fragment } from "preact";
22
import { SidebarPanel, Empty } from "../../sidebar/SidebarPanel";
33
import { useStore } from "../../../store/react-bindings";
44
import { RenderReason } from "../../../../adapter/shared/renderReasons";
@@ -53,7 +53,18 @@ export function RenderReasons() {
5353
{hasReasons ? ":" : ""}
5454
</dt>
5555
<dd class="render-reason-value">
56-
{hasReasons && reason!.items!.join(", ")}
56+
{hasReasons &&
57+
(reason.type === RenderReason.HOOKS_CHANGED ? (
58+
<>
59+
{reason!.items!.map(item => (
60+
<span class="hook-number va-middle" key={item}>
61+
{+item + 1}
62+
</span>
63+
))}
64+
</>
65+
) : (
66+
reason!.items!.join(", ")
67+
))}
5768
</dd>
5869
</dl>
5970
) : (

src/view/components/profiler/data/commits.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,9 @@ export function createProfiler(): ProfilerState {
136136

137137
// Render reasons
138138
const activeReason = computed(() => {
139-
if (activeCommit.value !== null) {
140-
const commitId = activeCommit.value.commitRootId;
141-
const reason = renderReasons.value.get(commitId);
142-
if (reason) {
143-
return reason.get(selectedNodeId.value) || null;
144-
}
139+
const reason = renderReasons.value.get(activeCommitIdx.value);
140+
if (reason) {
141+
return reason.get(selectedNodeId.value) || null;
145142
}
146143

147144
return null;

src/view/components/sidebar/inspect/ElementProps.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export function ElementProps(props: Props) {
3737
value={item.value}
3838
onChange={v => onChange && onChange(v, id, item)}
3939
depth={item.depth}
40+
index={item.index}
4041
/>
4142
);
4243
})}
@@ -57,6 +58,7 @@ export interface SingleProps {
5758
onChange?: (value: any) => void;
5859
onCollapse?: (path: string) => void;
5960
depth: number;
61+
index?: number;
6062
}
6163

6264
export function SingleItem(props: SingleProps) {
@@ -115,6 +117,9 @@ export function SingleItem(props: SingleProps) {
115117
onClick={onClick}
116118
>
117119
<Arrow />
120+
{props.index !== undefined && (
121+
<span class="hook-number">{props.index + 1}</span>
122+
)}
118123
<span
119124
class={`${s.name} ${s.nameEditable}`}
120125
data-testid="prop-name"
@@ -131,10 +136,15 @@ export function SingleItem(props: SingleProps) {
131136
)}
132137
{!collapseable && (
133138
<Fragment>
139+
{props.index !== undefined && (
140+
<span class={s.noCollapse}>
141+
<span class="hook-number">{props.index + 1}</span>
142+
</span>
143+
)}
134144
<span
135-
class={`${s.name} ${s.noCollapse} ${s.nameStatic} ${
136-
editable ? s.nameEditable : ""
137-
}`}
145+
class={`${s.name} ${
146+
props.index === undefined ? s.noCollapse : ""
147+
} ${s.nameStatic} ${editable ? s.nameEditable : ""}`}
138148
data-testid="prop-name"
139149
data-type={value !== "__preact_empty__" ? type : "empty"}
140150
>

0 commit comments

Comments
 (0)