Skip to content

Commit 75726fa

Browse files
author
Brian Vaughn
authored
DevTools fix props editing for host components (#20055)
1 parent 51a3aa6 commit 75726fa

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

packages/react-devtools-shared/src/__tests__/editing-test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ describe('editing interface', () => {
2828
bridge = global.bridge;
2929
store = global.store;
3030
store.collapseNodesByDefault = false;
31+
store.componentFilters = [];
3132

3233
PropTypes = require('prop-types');
3334
React = require('react');
@@ -37,8 +38,10 @@ describe('editing interface', () => {
3738
describe('props', () => {
3839
let committedClassProps;
3940
let committedFunctionProps;
41+
let inputRef;
4042
let classID;
4143
let functionID;
44+
let hostComponentID;
4245

4346
async function mountTestApp() {
4447
class ClassComponent extends React.Component {
@@ -60,6 +63,8 @@ describe('editing interface', () => {
6063
return null;
6164
}
6265

66+
inputRef = React.createRef(null);
67+
6368
const container = document.createElement('div');
6469
await utils.actAsync(() =>
6570
ReactDOM.render(
@@ -76,13 +81,15 @@ describe('editing interface', () => {
7681
shallow="initial"
7782
/>
7883
,
84+
<input ref={inputRef} onChange={jest.fn()} value="initial" />
7985
</>,
8086
container,
8187
),
8288
);
8389

8490
classID = ((store.getElementIDAtIndex(0): any): number);
8591
functionID = ((store.getElementIDAtIndex(1): any): number);
92+
hostComponentID = ((store.getElementIDAtIndex(2): any): number);
8693

8794
expect(committedClassProps).toStrictEqual({
8895
array: [1, 2, 3],
@@ -98,6 +105,7 @@ describe('editing interface', () => {
98105
},
99106
shallow: 'initial',
100107
});
108+
expect(inputRef.current.value).toBe('initial');
101109
}
102110

103111
it('should have editable values', async () => {
@@ -380,6 +388,25 @@ describe('editing interface', () => {
380388
object: {},
381389
});
382390
});
391+
392+
it('should support editing host component values', async () => {
393+
await mountTestApp();
394+
395+
function overrideProps(id, path, value) {
396+
const rendererID = utils.getRendererID();
397+
bridge.send('overrideValueAtPath', {
398+
id,
399+
path,
400+
rendererID,
401+
type: 'props',
402+
value,
403+
});
404+
flushPendingUpdates();
405+
}
406+
407+
overrideProps(hostComponentID, ['value'], 'updated');
408+
expect(inputRef.current.value).toBe('updated');
409+
});
383410
});
384411

385412
describe('state', () => {

packages/react-devtools-shared/src/backend/renderer.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2888,18 +2888,25 @@ export function attach(
28882888
}
28892889
break;
28902890
case 'props':
2891-
if (instance === null) {
2892-
if (typeof overrideProps === 'function') {
2893-
overrideProps(fiber, path, value);
2894-
}
2895-
} else {
2896-
fiber.pendingProps = copyWithSet(instance.props, path, value);
2897-
instance.forceUpdate();
2891+
switch (fiber.tag) {
2892+
case ClassComponent:
2893+
fiber.pendingProps = copyWithSet(instance.props, path, value);
2894+
instance.forceUpdate();
2895+
break;
2896+
default:
2897+
if (typeof overrideProps === 'function') {
2898+
overrideProps(fiber, path, value);
2899+
}
2900+
break;
28982901
}
28992902
break;
29002903
case 'state':
2901-
setInObject(instance.state, path, value);
2902-
instance.forceUpdate();
2904+
switch (fiber.tag) {
2905+
case ClassComponent:
2906+
setInObject(instance.state, path, value);
2907+
instance.forceUpdate();
2908+
break;
2909+
}
29032910
break;
29042911
}
29052912
}

0 commit comments

Comments
 (0)