General problem is that sometimes developers are using data objects which are more sophisticated than raw JS objects and arrays. Typically, these objects are represented as some facade class at the top level holding an actual state inside. Navigating through such an objects in props as well as in state is clumsy and the property inspector is almost unusable.
There is a number of issues on this topic (https://github.com/facebook/react-devtools/issues/83, https://github.com/facebook/react-devtools/issues/52). And there was an attempt to solve it in the PR specifically for ImmutableJS: https://github.com/facebook/react-devtools/pull/149
In this PR I attempt to solve the problem in the way that it would be easy for data framework developers to customize the appearance of data objects in the inspector. I'm doing it to make NestedReact models and collections look good in the inspector, but it's trivial to do it for any other data library including ImmutableJS (which I can do as well to resolve that pool of duplicate issues as soon as this PR will be accepted).
Idea is to attach state inspector functions to the object's prototype, which will take an object instance and return plain JS object or array (whatever is appropriate for the particular case). Whenever an object has state inspector it will be used to transform its state. Using BackboneJS as an example, something like this needs to be done to make models and collections look good:
if (__REACT_DEVTOOLS_GLOBAL_HOOK__) {
const { addInnerStateInspector } = __REACT_DEVTOOLS_GLOBAL_HOOK__;
if (typeof addInnerStateInspector === 'function') {
addInnerStateInspector( Backbone.Model, x => x.attributes );
addInnerStateInspector( Backbone.Collection, x => x.models );
}
}
Another example - Date
instances currently appears as an empty object (https://github.com/facebook/react-devtools/issues/388). Which is fixed by this PR in the following way:
addInnerStateInspector( Date, ( x : Date ) => ({
local : `${ x.toDateString() } ${ x.toTimeString() }`,
iso : x.toISOString(),
timestamp : x.getTime(),
});
This API can be used internally to improve the appearance of built-in JS classes, by data framework developers to make their custom classes appear well, and by regular developers as well.
In the case of the more sophisticated data structure, the corresponding raw JS representation can be calculated inside of the inspector functions and memorized in the data object's instance (which will work perfectly in case of ImmutableJS).
P.S.: One more issue this PR resolves (https://github.com/facebook/react-devtools/issues/390) is an exception being thrown when you're trying to inspect an object with get prop(){...}
calculated properties defined on the prototype.