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

DevTools fix props editing for host components #20055

Merged
merged 1 commit into from Oct 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 27 additions & 0 deletions packages/react-devtools-shared/src/__tests__/editing-test.js
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
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