Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(react-devtools-shared): useDebugValue with complex types #18070

Merged
merged 5 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`InspectedElementContext display complex values of useDebugValue: DisplayedComplexValue 1`] = `
{
"id": 2,
"owners": null,
"context": null,
"hooks": [
{
"id": null,
"isStateEditable": false,
"name": "DebuggableHook",
"value": {
"foo": 2
},
"subHooks": [
{
"id": 0,
"isStateEditable": true,
"name": "State",
"value": 1,
"subHooks": []
}
]
}
],
"props": {},
"state": null
}
`;

exports[`InspectedElementContext should dehydrate complex nested values when requested: 1: Initially inspect element 1`] = `
{
"id": 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1571,4 +1571,54 @@ describe('InspectedElementContext', () => {

done();
});

it('display complex values of useDebugValue', async done => {
let getInspectedElementPath: GetInspectedElementPath = ((null: any): GetInspectedElementPath);
let inspectedElement = null;
function Suspender({target}) {
const context = React.useContext(InspectedElementContext);
getInspectedElementPath = context.getInspectedElementPath;
inspectedElement = context.getInspectedElement(target);
return null;
}

const container = document.createElement('div');

function useDebuggableHook() {
React.useDebugValue({foo: 2});
React.useState(1);
return 1;
}
function DisplayedComplexValue() {
useDebuggableHook();
return null;
}

await utils.actAsync(() =>
ReactDOM.render(<DisplayedComplexValue />, container),
);

const ignoredComplexValueIndex = 0;
const ignoredComplexValueId = ((store.getElementIDAtIndex(
ignoredComplexValueIndex,
): any): number);
await utils.actAsync(
() =>
TestRenderer.create(
<Contexts
defaultSelectedElementID={ignoredComplexValueId}
defaultSelectedElementIndex={ignoredComplexValueIndex}>
<React.Suspense fallback={null}>
<Suspender target={ignoredComplexValueId} />
</React.Suspense>
</Contexts>,
),
false,
);
expect(getInspectedElementPath).not.toBeNull();
expect(inspectedElement).not.toBeNull();
expect(inspectedElement).toMatchSnapshot('DisplayedComplexValue');

done();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import EditableValue from './EditableValue';
import ExpandCollapseToggle from './ExpandCollapseToggle';
import {InspectedElementContext} from './InspectedElementContext';
import KeyValue from './KeyValue';
import {serializeHooksForCopy} from '../utils';
import {getMetaValueLabel, serializeHooksForCopy} from '../utils';
import styles from './HooksTree.css';
import useContextMenu from '../../ContextMenu/useContextMenu';
import {meta} from '../../../hydration';
Expand Down Expand Up @@ -202,17 +202,11 @@ function HookView({canEditHooks, hook, id, inspectPath, path}: HookViewProps) {
className={name !== '' ? styles.Name : styles.NameAnonymous}>
{name || 'Anonymous'}
</span>
<span className={styles.Value} onClick={toggleIsOpen}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should only be shown if the hook is collapsed. Otherwise, the <KeyValue> component should be rendered as it enables the complex value to be expanded and inspected.

So something like this:

<div className={styles.Hook}>
  <div ref={contextMenuTriggerRef} className={styles.NameValueRow}>
    <ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
    <span
      onClick={toggleIsOpen}
      className={name !== '' ? styles.Name : styles.NameAnonymous}>
      {name || 'Anonymous'}
    </span>
    <span className={styles.Value} onClick={toggleIsOpen}>
      {isOpen || getMetaValueLabel(value)}
    </span>
  </div>
  <div className={styles.Children} hidden={!isOpen}>
    <KeyValue 
      depth={1} 
      alphaSort={false} 
      inspectPath={inspectPath} 
      name="DebugValue" 
      path={path.concat(['value'])} 
      pathRoot="hooks"  
      value={value} 
    />
    {subHooksView}
  </div>
</div>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, the label should work like this when toggling:
Custom hook label

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep that's what I wanted. I guess in this PR the debug value is still displayed on the same line as "CustomObject:" when expanded?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the string preview just stayed visible but the ability to expand the complex value below was gone. I added it back in 32bac9e 😄

{getMetaValueLabel(value)}
</span>
</div>
<div className={styles.Children} hidden={!isOpen}>
<KeyValue
depth={1}
alphaSort={false}
inspectPath={inspectPath}
name="DebugValue"
path={path.concat(['value'])}
pathRoot="hooks"
value={value}
/>
{subHooksView}
</div>
</div>
Expand Down