mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
e7d213dfb0
# Summary - `compiledWithForget` field for nodes is now propagated from the backend to frontend profiler stores - Corresponding node with such field will have a `✨` prefix displayed before its displayName <img width="1728" alt="Screenshot 2024-05-07 at 15 05 37" src="https://github.com/facebook/react/assets/28902667/fe044d40-52cb-4169-867d-5a2d72e3275b"> - Badges are now displayed on the right panel when some fiber is selected in a specific commit <img width="1728" alt="Screenshot 2024-05-07 at 15 05 50" src="https://github.com/facebook/react/assets/28902667/297ba5ca-404d-4172-b9bf-bfed7978afe5"> - Badges are also displayed when user hovers over some node in the tree <img width="1728" alt="Screenshot 2024-05-07 at 15 25 22" src="https://github.com/facebook/react/assets/28902667/bee47884-61d1-46b6-a483-717fc148893a">
162 lines
3.8 KiB
JavaScript
162 lines
3.8 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
*/
|
|
|
|
import * as React from 'react';
|
|
import {useContext} from 'react';
|
|
|
|
import {ProfilerContext} from './ProfilerContext';
|
|
import {StoreContext} from '../context';
|
|
|
|
import styles from './WhatChanged.css';
|
|
|
|
function hookIndicesToString(indices: Array<number>): string {
|
|
// This is debatable but I think 1-based might ake for a nicer UX.
|
|
const numbers = indices.map(value => value + 1);
|
|
|
|
switch (numbers.length) {
|
|
case 0:
|
|
return 'No hooks changed';
|
|
case 1:
|
|
return `Hook ${numbers[0]} changed`;
|
|
case 2:
|
|
return `Hooks ${numbers[0]} and ${numbers[1]} changed`;
|
|
default:
|
|
return `Hooks ${numbers.slice(0, numbers.length - 1).join(', ')} and ${
|
|
numbers[numbers.length - 1]
|
|
} changed`;
|
|
}
|
|
}
|
|
|
|
type Props = {
|
|
fiberID: number,
|
|
};
|
|
|
|
export default function WhatChanged({fiberID}: Props): React.Node {
|
|
const {profilerStore} = useContext(StoreContext);
|
|
const {rootID, selectedCommitIndex} = useContext(ProfilerContext);
|
|
|
|
// TRICKY
|
|
// Handle edge case where no commit is selected because of a min-duration filter update.
|
|
// If the commit index is null, suspending for data below would throw an error.
|
|
// TODO (ProfilerContext) This check should not be necessary.
|
|
if (selectedCommitIndex === null) {
|
|
return null;
|
|
}
|
|
|
|
const {changeDescriptions} = profilerStore.getCommitData(
|
|
((rootID: any): number),
|
|
selectedCommitIndex,
|
|
);
|
|
|
|
if (changeDescriptions === null) {
|
|
return null;
|
|
}
|
|
|
|
const changeDescription = changeDescriptions.get(fiberID);
|
|
if (changeDescription == null) {
|
|
return null;
|
|
}
|
|
|
|
const {context, didHooksChange, hooks, isFirstMount, props, state} =
|
|
changeDescription;
|
|
|
|
if (isFirstMount) {
|
|
return (
|
|
<div className={styles.Component}>
|
|
<label className={styles.Label}>Why did this render?</label>
|
|
<div className={styles.Item}>
|
|
This is the first time the component rendered.
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const changes = [];
|
|
|
|
if (context === true) {
|
|
changes.push(
|
|
<div key="context" className={styles.Item}>
|
|
• Context changed
|
|
</div>,
|
|
);
|
|
} else if (
|
|
typeof context === 'object' &&
|
|
context !== null &&
|
|
context.length !== 0
|
|
) {
|
|
changes.push(
|
|
<div key="context" className={styles.Item}>
|
|
• Context changed:
|
|
{context.map(key => (
|
|
<span key={key} className={styles.Key}>
|
|
{key}
|
|
</span>
|
|
))}
|
|
</div>,
|
|
);
|
|
}
|
|
|
|
if (didHooksChange) {
|
|
if (Array.isArray(hooks)) {
|
|
changes.push(
|
|
<div key="hooks" className={styles.Item}>
|
|
• {hookIndicesToString(hooks)}
|
|
</div>,
|
|
);
|
|
} else {
|
|
changes.push(
|
|
<div key="hooks" className={styles.Item}>
|
|
• Hooks changed
|
|
</div>,
|
|
);
|
|
}
|
|
}
|
|
|
|
if (props !== null && props.length !== 0) {
|
|
changes.push(
|
|
<div key="props" className={styles.Item}>
|
|
• Props changed:
|
|
{props.map(key => (
|
|
<span key={key} className={styles.Key}>
|
|
{key}
|
|
</span>
|
|
))}
|
|
</div>,
|
|
);
|
|
}
|
|
|
|
if (state !== null && state.length !== 0) {
|
|
changes.push(
|
|
<div key="state" className={styles.Item}>
|
|
• State changed:
|
|
{state.map(key => (
|
|
<span key={key} className={styles.Key}>
|
|
{key}
|
|
</span>
|
|
))}
|
|
</div>,
|
|
);
|
|
}
|
|
|
|
if (changes.length === 0) {
|
|
changes.push(
|
|
<div key="nothing" className={styles.Item}>
|
|
The parent component rendered.
|
|
</div>,
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<label className={styles.Label}>Why did this render?</label>
|
|
{changes}
|
|
</div>
|
|
);
|
|
}
|