@samitouri / QOS-React / commits / 75726fadfd

DevTools fix props editing for host components (#20055)

Brian Vaughn committed Oct 19, 2020 at 15:21 UTC 75726fadfd4ab063390805bf5baab966c8523d2c
2 files changed +43 -9
packages/react-devtools-shared/src/__tests__/editing-test.js
+27
@@ -28,6 +28,7 @@ describe('editing interface', () => {
28 bridge = global.bridge;
29 store = global.store;
30 store.collapseNodesByDefault = false;
31 + store.componentFilters = [];
32
33 PropTypes = require('prop-types');
34 React = require('react');
@@ -37,8 +38,10 @@ describe('editing interface', () => {
38 describe('props', () => {
39 let committedClassProps;
40 let committedFunctionProps;
41 + let inputRef;
42 let classID;
43 let functionID;
44 + let hostComponentID;
45
46 async function mountTestApp() {
47 class ClassComponent extends React.Component {
@@ -60,6 +63,8 @@ describe('editing interface', () => {
63 return null;
64 }
65
66 + inputRef = React.createRef(null);
67 +
68 const container = document.createElement('div');
69 await utils.actAsync(() =>
70 ReactDOM.render(
@@ -76,6 +81,7 @@ describe('editing interface', () => {
81 shallow="initial"
82 />
83 ,
84 + <input ref={inputRef} onChange={jest.fn()} value="initial" />
85 </>,
86 container,
87 ),
@@ -83,6 +89,7 @@ describe('editing interface', () => {
89
90 classID = ((store.getElementIDAtIndex(0): any): number);
91 functionID = ((store.getElementIDAtIndex(1): any): number);
92 + hostComponentID = ((store.getElementIDAtIndex(2): any): number);
93
94 expect(committedClassProps).toStrictEqual({
95 array: [1, 2, 3],
@@ -98,6 +105,7 @@ describe('editing interface', () => {
105 },
106 shallow: 'initial',
107 });
108 + expect(inputRef.current.value).toBe('initial');
109 }
110
111 it('should have editable values', async () => {
@@ -380,6 +388,25 @@ describe('editing interface', () => {
388 object: {},
389 });
390 });
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 + });
410 });
411
412 describe('state', () => {
packages/react-devtools-shared/src/backend/renderer.js
+16 -9
@@ -2888,18 +2888,25 @@ export function attach(
2888 }
2889 break;
2890 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;
2901 }
2902 break;
2903 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 + }
2910 break;
2911 }
2912 }