Updated hydration logic to handle custom objects
This commit is contained in:
parent
cb10c3d6da
commit
96f7646a1a
|
@ -0,0 +1,18 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
|
||||
class Custom {
|
||||
_number = 42;
|
||||
get number() {
|
||||
return this._number;
|
||||
}
|
||||
}
|
||||
|
||||
export default function CustomObject() {
|
||||
return <ChildComponent customObject={new Custom()} />;
|
||||
}
|
||||
|
||||
function ChildComponent(props: any) {
|
||||
return null;
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import Contexts from './Contexts';
|
||||
import CustomHooks from './CustomHooks';
|
||||
import CustomObject from './CustomObject';
|
||||
import NestedProps from './NestedProps';
|
||||
|
||||
// TODO Add Immutable JS example
|
||||
|
@ -14,6 +15,7 @@ export default function InspectableElements() {
|
|||
<NestedProps />
|
||||
<Contexts />
|
||||
<CustomHooks />
|
||||
<CustomObject />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -114,3 +114,25 @@ exports[`InspectedElementContext should poll for updates for the currently selec
|
|||
"state": null
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`InspectedElementContext should support custom objects with enumerable properties and getters: 1: mount 1`] = `
|
||||
[root]
|
||||
<Example>
|
||||
`;
|
||||
|
||||
exports[`InspectedElementContext should support custom objects with enumerable properties and getters: 2: Inspected element 2 1`] = `
|
||||
{
|
||||
"id": 2,
|
||||
"owners": null,
|
||||
"context": null,
|
||||
"events": null,
|
||||
"hooks": null,
|
||||
"props": {
|
||||
"data": {
|
||||
"_number": 42,
|
||||
"number": 42
|
||||
}
|
||||
},
|
||||
"state": null
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -257,4 +257,63 @@ describe('InspectedElementContext', () => {
|
|||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should support custom objects with enumerable properties and getters', async done => {
|
||||
class CustomData {
|
||||
_number = 42;
|
||||
get number() {
|
||||
return this._number;
|
||||
}
|
||||
set number(value) {
|
||||
this._number = value;
|
||||
}
|
||||
}
|
||||
|
||||
const descriptor = ((Object.getOwnPropertyDescriptor(
|
||||
CustomData.prototype,
|
||||
'number'
|
||||
): any): PropertyDescriptor<number>);
|
||||
descriptor.enumerable = true;
|
||||
Object.defineProperty(CustomData.prototype, 'number', descriptor);
|
||||
|
||||
const Example = ({ data }) => null;
|
||||
|
||||
const container = document.createElement('div');
|
||||
await utils.actAsync(() =>
|
||||
ReactDOM.render(<Example data={new CustomData()} />, container)
|
||||
);
|
||||
expect(store).toMatchSnapshot('1: mount');
|
||||
|
||||
const example = ((store.getElementAtIndex(0): any): Element);
|
||||
|
||||
let didFinish = false;
|
||||
|
||||
function Suspender({ target }) {
|
||||
const { read } = React.useContext(InspectedElementContext);
|
||||
const inspectedElement = read(target.id);
|
||||
expect(inspectedElement).toMatchSnapshot(
|
||||
`2: Inspected element ${target.id}`
|
||||
);
|
||||
didFinish = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
await utils.actAsync(
|
||||
() =>
|
||||
TestRenderer.create(
|
||||
<Contexts
|
||||
defaultSelectedElementID={example.id}
|
||||
defaultSelectedElementIndex={0}
|
||||
>
|
||||
<React.Suspense fallback={null}>
|
||||
<Suspender target={example} />
|
||||
</React.Suspense>
|
||||
</Contexts>
|
||||
),
|
||||
false
|
||||
);
|
||||
expect(didFinish).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -194,12 +194,7 @@ export function dehydrate(
|
|||
},
|
||||
};
|
||||
case 'object':
|
||||
if (
|
||||
level > LEVEL_THRESHOLD ||
|
||||
(data.constructor &&
|
||||
typeof data.constructor === 'function' &&
|
||||
data.constructor.name !== 'Object')
|
||||
) {
|
||||
if (level > LEVEL_THRESHOLD) {
|
||||
return createDehydrated(type, data, cleaned, path);
|
||||
} else {
|
||||
const res = {};
|
||||
|
|
Loading…
Reference in New Issue