Skip to content

null / undefined / NaN render as empty when displayDataTypes={false} #91

@patrickxunuo

Description

@patrickxunuo

Summary

When displayDataTypes={false} and no custom render is provided for JsonView.Null / JsonView.Undefined / JsonView.Nan, those values render as nothing — the row shows the key, colon, and then an empty space.

Rendered output for { "a": null, "b": 1 }:

"a":
"b": 1

Expected:

"a": null
"b": 1

Version

@uiw/react-json-view@2.0.0-alpha.41

Reproduction

import JsonView from '@uiw/react-json-view';

<JsonView
  value={{ a: null, b: undefined, c: NaN, d: 1, e: 'x' }}
  displayDataTypes={false}
/>

d and e render correctly. a, b, c render as empty.

Root cause

TypeInt, TypeString, TypeTrue/False, TypeFloat, TypeDate, TypeBigint all end with a child || <Comp ...>{children.toString()}</Comp> fallback, so when displayDataTypes={false} (hides the type label) and no custom render prop is set (so child is undefined), the value-text fallback still renders.

TypeNull, TypeUndefined, TypeNan in the same file (src/types/index.tsx) return just {child} with no fallback — so when displayDataTypes={false} and no render override exists, the JSX collapses to [false, undefined] → empty DOM.

Relevant code (cjs/types/index.js, mirrors src/types/index.tsx):

// TypeInt — OK (has fallback)
return (
  <>
    {displayDataTypes && (type || <Comp {...reset} style={style} />)}
    {child || <Comp {...reset} className="w-rjv-value">{children?.toString()}</Comp>}
  </>
);

// TypeNull — BUG (no fallback)
return (
  <>
    {displayDataTypes && (type || <Comp {...reset} style={style} />)}
    {child}
  </>
);

Suggested fix

Add the same fallback to TypeNull, TypeUndefined, and TypeNan:

// TypeNull
{child || <Comp {...reset} className="w-rjv-value">null</Comp>}

// TypeUndefined
{child || <Comp {...reset} className="w-rjv-value">undefined</Comp>}

// TypeNan
{child || <Comp {...reset} className="w-rjv-value">NaN</Comp>}

The default children for these types already exists in store/Types.ts initial state ('null', 'undefined', 'NaN'), so alternatively the fallback could reuse reset.children for consistency with the customizable initial state.

Current workaround

Provide an explicit render override:

<JsonView value={data} displayDataTypes={false}>
  <JsonView.Null
    render={(props, { type }) =>
      type === 'value' ? <span {...props}>null</span> : null
    }
  />
  <JsonView.Undefined
    render={(props, { type }) =>
      type === 'value' ? <span {...props}>undefined</span> : null
    }
  />
  <JsonView.Nan
    render={(props, { type }) =>
      type === 'value' ? <span {...props}>NaN</span> : null
    }
  />
</JsonView>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions