mirror of
https://github.com/facebook/react.git
synced 2026-02-26 02:54:59 +00:00
[DevTools] Display React.optimisticKey in key positions (#35760)
This commit is contained in:
committed by
GitHub
parent
57b79b0388
commit
e49335e961
131
packages/react-devtools-shared/src/__tests__/optimisticKeyDevToolsIntegration.js
vendored
Normal file
131
packages/react-devtools-shared/src/__tests__/optimisticKeyDevToolsIntegration.js
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* 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 {getVersionedRenderImplementation} from './utils';
|
||||
|
||||
describe('Store React.optimisticKey', () => {
|
||||
let act;
|
||||
let actAsync;
|
||||
let React;
|
||||
let TestRenderer;
|
||||
let bridge;
|
||||
let store;
|
||||
|
||||
let BridgeContext;
|
||||
let StoreContext;
|
||||
let TreeContext;
|
||||
|
||||
let dispatch;
|
||||
let state;
|
||||
|
||||
beforeAll(() => {
|
||||
// JSDDOM doesn't implement getClientRects so we're just faking one for testing purposes
|
||||
Element.prototype.getClientRects = function (this: Element) {
|
||||
const textContent = this.textContent;
|
||||
return [
|
||||
new DOMRect(1, 2, textContent.length, textContent.split('\n').length),
|
||||
];
|
||||
};
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
global.IS_REACT_ACT_ENVIRONMENT = true;
|
||||
|
||||
store = global.store;
|
||||
bridge = global.bridge;
|
||||
|
||||
React = require('react');
|
||||
|
||||
const utils = require('./utils');
|
||||
act = utils.act;
|
||||
actAsync = utils.actAsync;
|
||||
TestRenderer = utils.requireTestRenderer();
|
||||
|
||||
BridgeContext =
|
||||
require('react-devtools-shared/src/devtools/views/context').BridgeContext;
|
||||
StoreContext =
|
||||
require('react-devtools-shared/src/devtools/views/context').StoreContext;
|
||||
TreeContext = require('react-devtools-shared/src/devtools/views/Components/TreeContext');
|
||||
});
|
||||
|
||||
const {render} = getVersionedRenderImplementation();
|
||||
|
||||
const Capture = () => {
|
||||
dispatch = React.useContext(TreeContext.TreeDispatcherContext);
|
||||
state = React.useContext(TreeContext.TreeStateContext);
|
||||
return null;
|
||||
};
|
||||
|
||||
const Contexts = () => {
|
||||
return (
|
||||
<BridgeContext.Provider value={bridge}>
|
||||
<StoreContext.Provider value={store}>
|
||||
<TreeContext.TreeContextController>
|
||||
<Capture />
|
||||
</TreeContext.TreeContextController>
|
||||
</StoreContext.Provider>
|
||||
</BridgeContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// @reactVersion >= 19.3
|
||||
it('is included in the tree', async () => {
|
||||
if (React.optimisticKey === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
function Component() {
|
||||
return null;
|
||||
}
|
||||
|
||||
await actAsync(() => {
|
||||
render(<Component key={React.optimisticKey} />);
|
||||
});
|
||||
|
||||
expect(store).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
<Component key="React.optimisticKey">
|
||||
`);
|
||||
expect(store.getElementAtIndex(0)).toEqual(
|
||||
expect.objectContaining({key: 'React.optimisticKey'}),
|
||||
);
|
||||
});
|
||||
|
||||
// @reactVersion >= 19.3
|
||||
it('is searchable', async () => {
|
||||
if (React.optimisticKey === undefined) {
|
||||
return;
|
||||
}
|
||||
await actAsync(() => {
|
||||
render(<React.Fragment key={React.optimisticKey} />);
|
||||
});
|
||||
let renderer;
|
||||
act(() => (renderer = TestRenderer.create(<Contexts />)));
|
||||
|
||||
expect(state).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
<Fragment key="React.optimisticKey">
|
||||
`);
|
||||
|
||||
act(() => dispatch({type: 'SET_SEARCH_TEXT', payload: 'optimistic'}));
|
||||
act(() => renderer.update(<Contexts />));
|
||||
|
||||
expect(state).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
<Fragment key="React.optimisticKey">
|
||||
`);
|
||||
|
||||
act(() => dispatch({type: 'SET_SEARCH_TEXT', payload: 'react'}));
|
||||
act(() => renderer.update(<Contexts />));
|
||||
|
||||
expect(state).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
→ <Fragment key="React.optimisticKey">
|
||||
`);
|
||||
});
|
||||
});
|
||||
@@ -2606,7 +2606,12 @@ export function attach(
|
||||
|
||||
// This check is a guard to handle a React element that has been modified
|
||||
// in such a way as to bypass the default stringification of the "key" property.
|
||||
const keyString = key === null ? null : String(key);
|
||||
const keyString =
|
||||
key === null
|
||||
? null
|
||||
: key === REACT_OPTIMISTIC_KEY
|
||||
? 'React.optimisticKey'
|
||||
: String(key);
|
||||
const keyStringID = getStringID(keyString);
|
||||
|
||||
const nameProp =
|
||||
@@ -6180,7 +6185,10 @@ export function attach(
|
||||
return {
|
||||
displayName: getDisplayNameForFiber(fiber) || 'Anonymous',
|
||||
id: instance.id,
|
||||
key: fiber.key === REACT_OPTIMISTIC_KEY ? null : fiber.key,
|
||||
key:
|
||||
fiber.key === REACT_OPTIMISTIC_KEY
|
||||
? 'React.optimisticKey'
|
||||
: fiber.key,
|
||||
env: null,
|
||||
stack:
|
||||
fiber._debugOwner == null || fiber._debugStack == null
|
||||
@@ -6196,7 +6204,7 @@ export function attach(
|
||||
key:
|
||||
componentInfo.key == null ||
|
||||
componentInfo.key === REACT_OPTIMISTIC_KEY
|
||||
? null
|
||||
? 'React.optimisticKey'
|
||||
: componentInfo.key,
|
||||
env: componentInfo.env == null ? null : componentInfo.env,
|
||||
stack:
|
||||
@@ -7123,7 +7131,12 @@ export function attach(
|
||||
// Does the component have legacy context attached to it.
|
||||
hasLegacyContext,
|
||||
|
||||
key: key != null && key !== REACT_OPTIMISTIC_KEY ? key : null,
|
||||
key:
|
||||
key != null
|
||||
? key === REACT_OPTIMISTIC_KEY
|
||||
? 'React.optimisticKey'
|
||||
: key
|
||||
: null,
|
||||
|
||||
type: elementType,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user