Skip to content

Commit

Permalink
DevTools fix props editing for host components (facebook#20055)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn authored and koto committed Jun 15, 2021
1 parent ce5a6aa commit 00d4f8b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
27 changes: 27 additions & 0 deletions packages/react-devtools-shared/src/__tests__/editing-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('editing interface', () => {
bridge = global.bridge;
store = global.store;
store.collapseNodesByDefault = false;
store.componentFilters = [];

PropTypes = require('prop-types');
React = require('react');
Expand All @@ -37,8 +38,10 @@ describe('editing interface', () => {
describe('props', () => {
let committedClassProps;
let committedFunctionProps;
let inputRef;
let classID;
let functionID;
let hostComponentID;

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

inputRef = React.createRef(null);

const container = document.createElement('div');
await utils.actAsync(() =>
ReactDOM.render(
Expand All @@ -76,13 +81,15 @@ describe('editing interface', () => {
shallow="initial"
/>
,
<input ref={inputRef} onChange={jest.fn()} value="initial" />
</>,
container,
),
);

classID = ((store.getElementIDAtIndex(0): any): number);
functionID = ((store.getElementIDAtIndex(1): any): number);
hostComponentID = ((store.getElementIDAtIndex(2): any): number);

expect(committedClassProps).toStrictEqual({
array: [1, 2, 3],
Expand All @@ -98,6 +105,7 @@ describe('editing interface', () => {
},
shallow: 'initial',
});
expect(inputRef.current.value).toBe('initial');
}

it('should have editable values', async () => {
Expand Down Expand Up @@ -380,6 +388,25 @@ describe('editing interface', () => {
object: {},
});
});

it('should support editing host component values', async () => {
await mountTestApp();

function overrideProps(id, path, value) {
const rendererID = utils.getRendererID();
bridge.send('overrideValueAtPath', {
id,
path,
rendererID,
type: 'props',
value,
});
flushPendingUpdates();
}

overrideProps(hostComponentID, ['value'], 'updated');
expect(inputRef.current.value).toBe('updated');
});
});

describe('state', () => {
Expand Down
25 changes: 16 additions & 9 deletions packages/react-devtools-shared/src/backend/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2888,18 +2888,25 @@ export function attach(
}
break;
case 'props':
if (instance === null) {
if (typeof overrideProps === 'function') {
overrideProps(fiber, path, value);
}
} else {
fiber.pendingProps = copyWithSet(instance.props, path, value);
instance.forceUpdate();
switch (fiber.tag) {
case ClassComponent:
fiber.pendingProps = copyWithSet(instance.props, path, value);
instance.forceUpdate();
break;
default:
if (typeof overrideProps === 'function') {
overrideProps(fiber, path, value);
}
break;
}
break;
case 'state':
setInObject(instance.state, path, value);
instance.forceUpdate();
switch (fiber.tag) {
case ClassComponent:
setInObject(instance.state, path, value);
instance.forceUpdate();
break;
}
break;
}
}
Expand Down

0 comments on commit 00d4f8b

Please sign in to comment.