-
Couldn't load subscription status.
- Fork 32
Description
Expansion state is lost when src prop updates to an object missing a previously expanded path.
Description:
The component's internal expansion state is destructively modified when the src prop is updated. If a previously expanded path does not exist in the new src object, that path is permanently removed from the expansion state. This causes a poor user experience when navigating between objects that have slightly different data structures, as the user's manual expansions are lost.
Steps to Reproduce:
- Render the
JsonViewcomponent with an initialsrcobject, for example:{ "request": { "header": { "id": "123" } }, "other_data": {} } - Manually expand the
requestnode, and then expand the nestedheadernode. - Update the component by passing a new
srcprop that is missing theheadernode, for example:{ "request": { "body": { "id": "456" } }, "other_data": {} } - Update the component again by passing the original
srcprop from step 1.
Actual Behavior:
In step 4, the header node is rendered as collapsed. The user's interaction state from step 2 has been lost.
Expected Behavior:
The component's internal expansion state should be preserved across src updates. In step 4, the header node should be rendered as expanded, just as the user left it in step 2. The absence of a path in one src object should not purge that path's state for subsequent re-renders.
Suggested Fix / Architectural Analysis:
The root cause of this issue is the decentralized state management for collapsed nodes.
In src/components/object-node.tsx, the collapse state for each individual object/array is managed by a local useState hook:
// in src/components/object-node.tsx
const [fold, _setFold] = useState(isCollapsed(...))Because this state is local to each ObjectNode instance, it is destroyed when that component unmounts. When the src prop of the main JsonView component is updated with an object that has a different structure, the old component instances are unmounted, and their local state is permanently lost.
A more robust architectural solution would be to centralize the expansion state.
The expansion state for the entire tree could be managed within the top-level JsonView component (src/components/json-view.tsx). This could be a single state object that maps node paths to their collapsed status (e.g., collapsedPaths: { 'request.header': false }).