Pretty Printing JSON mit React


96

Ich verwende ReactJS und ein Teil meiner App erfordert hübsch gedrucktes JSON.

Ich bekomme JSON wie: { "foo": 1, "bar": 2 }und wenn ich das JSON.stringify(obj, null, 4)in der Browserkonsole durchlaufe , wird es ziemlich gedruckt, aber wenn ich es in diesem Reaktionsschnipsel verwende:

render: function() {
  var json = this.getStateFromFlux().json;
  return (
    <div>
      <JsonSubmitter onSubmit={this.onSubmit} />
      { JSON.stringify(json, null, 2) }
    </div>
  );
},

es macht grobe JSON, die aussieht wie "{ \"foo\" : 2, \"bar\": 2}\n".

Wie kann ich diese Zeichen richtig interpretieren? {


4
Hast du es versucht JSON.stringify(json, null, "\t")?
Brroshan

Es stellte sich heraus, dass ich einen dummen Fehler hatte, bei dem this.getStateFromFlux().jsonbereits eine Zeichenfolge zurückgegeben wurde. Ich habe es so geändert, dass es stattdessen ein JS-Objekt enthält, und es funktioniert jetzt einwandfrei.
Brandon

Antworten:


197

Sie müssen entweder das BRTag entsprechend in die resultierende Zeichenfolge einfügen oder beispielsweise ein PRETag verwenden, damit die Formatierung des Tags erhalten stringifybleibt:

var data = { a: 1, b: 2 };

var Hello = React.createClass({
    render: function() {
        return <div><pre>{JSON.stringify(data, null, 2) }</pre></div>;
    }
});

React.render(<Hello />, document.getElementById('container'));

Arbeitsbeispiel .

Aktualisieren

class PrettyPrintJson extends React.Component {
    render() {
         // data could be a prop for example
         // const { data } = this.props;
         return (<div><pre>{JSON.stringify(data, null, 2) }</pre></div>);
    }
}

ReactDOM.render(<PrettyPrintJson/>, document.getElementById('container'));

Beispiel

Zustandslose Funktionskomponente, Reaktion .14 oder höher

const PrettyPrintJson = ({data}) => {
    // (destructured) data could be a prop for example
    return (<div><pre>{ JSON.stringify(data, null, 2) }</pre></div>);
}

Oder, ...

const PrettyPrintJson = ({data}) => (<div><pre>{ 
    JSON.stringify(data, null, 2) }</pre></div>);

Arbeitsbeispiel

Memo / 16.6+

(Vielleicht möchten Sie sogar ein Memo verwenden, 16.6+)

const PrettyPrintJson = React.memo(({data}) => (<div><pre>{
    JSON.stringify(data, null, 2) }</pre></div>));

2
Danke dafür! Wusste nichts über den optionalen Parameter JSON.stringify. Javascript ist fantastisch ^^
Marcel Ennix

React ist jetzt veraltet, verwenden Sie stattdessen ReactDOM
Brane

Das ist perfekt - die einfachste Lösung ist immer die beste! Ich empfehle das Hinzufügen highlight.js für einige Syntax - Hervorhebung und Thematisierung Pep.
KeepingItClassy

Das ist wunderschön
JChao

Die <pre> -Tag-Lösung funktioniert perfekt und das ist der richtige Weg!
Vikram K

21

Nur um die Antwort von WiredPrairie ein wenig zu erweitern, eine Mini-Komponente, die geöffnet und geschlossen werden kann.

Kann verwendet werden wie:

<Pretty data={this.state.data}/>

Geben Sie hier die Bildbeschreibung ein

export default React.createClass({

    style: {
        backgroundColor: '#1f4662',
        color: '#fff',
        fontSize: '12px',
    },

    headerStyle: {
        backgroundColor: '#193549',
        padding: '5px 10px',
        fontFamily: 'monospace',
        color: '#ffc600',
    },

    preStyle: {
        display: 'block',
        padding: '10px 30px',
        margin: '0',
        overflow: 'scroll',
    },

    getInitialState() {
        return {
            show: true,
        };
    },

    toggle() {
        this.setState({
            show: !this.state.show,
        });
    },

    render() {
        return (
            <div style={this.style}>
                <div style={this.headerStyle} onClick={ this.toggle }>
                    <strong>Pretty Debug</strong>
                </div>
                {( this.state.show ?
                    <pre style={this.preStyle}>
                        {JSON.stringify(this.props.data, null, 2) }
                    </pre> : false )}
            </div>
        );
    }
});

Aktualisieren

Ein moderner Ansatz (jetzt, da createClass auf dem Weg nach draußen ist)

import styles from './DebugPrint.css'

import autoBind from 'react-autobind'
import classNames from 'classnames'
import React from 'react'

export default class DebugPrint extends React.PureComponent {
  constructor(props) {
    super(props)
    autoBind(this)
    this.state = {
      show: false,
    }
  }    

  toggle() {
    this.setState({
      show: !this.state.show,
    });
  }

  render() {
    return (
      <div style={styles.root}>
        <div style={styles.header} onClick={this.toggle}>
          <strong>Debug</strong>
        </div>
        {this.state.show 
          ? (
            <pre style={styles.pre}>
              {JSON.stringify(this.props.data, null, 2) }
            </pre>
          )
          : null
        }
      </div>
    )
  }
}

Und deine Style-Datei

.root {backgroundColor: '# 1f4662'; Farbe: '#fff'; fontSize: '12px'; }}

.header {backgroundColor: '# 193549'; Polsterung: '5px 10px'; fontFamily: 'monospace'; Farbe: '# ffc600'; }}

.pre {display: 'block'; Polsterung: '10px 30px'; Rand: '0'; Überlauf: 'scroll'; }}


Das ist auf jeden Fall fantastisch +1! Ich mache solche kleinen Dinge zum Debuggen und Testen von Daten, bevor ich die Komponente selbst ausbaue. Dieser ist wirklich großartig!
Ryan Hamblin

1
So konvertieren Sie in eine Komponente: toddmotto.com/react-create-class-versus-component
whitneyland

11

Die ' React-JSON-Ansicht ' bietet eine Lösung zum Rendern von JSON-Zeichenfolgen.

import ReactJson from 'react-json-view';
<ReactJson src={my_important_json} theme="monokai" />

5
const getJsonIndented = (obj) => JSON.stringify(newObj, null, 4).replace(/["{[,\}\]]/g, "")

const JSONDisplayer = ({children}) => (
    <div>
        <pre>{getJsonIndented(children)}</pre>
    </div>
)

Dann können Sie es einfach verwenden:

const Demo = (props) => {
   ....
   return <JSONDisplayer>{someObj}<JSONDisplayer>
}

0

Hier ist eine Demo react_hooks_debug_print.htmlin React Hooks, die auf Chris 'Antwort basiert. Das Beispiel für json-Daten stammt von https://json.org/example.html .

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

    <!-- Don't use this in production: -->
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script src="https://raw.githubusercontent.com/cassiozen/React-autobind/master/src/autoBind.js"></script>

    <script type="text/babel">

let styles = {
  root: { backgroundColor: '#1f4662', color: '#fff', fontSize: '12px', },
  header: { backgroundColor: '#193549', padding: '5px 10px', fontFamily: 'monospace', color: '#ffc600', },
  pre: { display: 'block', padding: '10px 30px', margin: '0', overflow: 'scroll', }
}

let data = {
  "glossary": {
    "title": "example glossary",
    "GlossDiv": {
      "title": "S",
      "GlossList": {
        "GlossEntry": {
          "ID": "SGML",
          "SortAs": "SGML",
          "GlossTerm": "Standard Generalized Markup Language",
          "Acronym": "SGML",
          "Abbrev": "ISO 8879:1986",
          "GlossDef": {
            "para": "A meta-markup language, used to create markup languages such as DocBook.",
            "GlossSeeAlso": [
              "GML",
              "XML"
            ]
          },
          "GlossSee": "markup"
        }
      }
    }
  }
}

const DebugPrint = () => {
  const [show, setShow] = React.useState(false);

  return (
    <div key={1} style={styles.root}>
    <div style={styles.header} onClick={ ()=>{setShow(!show)} }>
        <strong>Debug</strong>
    </div>
    { show 
      ? (
      <pre style={styles.pre}>
       {JSON.stringify(data, null, 2) }
      </pre>
      )
      : null
    }
    </div>
  )
}

ReactDOM.render(
  <DebugPrint data={data} />, 
  document.getElementById('root')
);

    </script>

  </body>
</html>

Oder fügen Sie den Stil wie folgt in die Kopfzeile ein:

    <style>
.root { background-color: #1f4662; color: #fff; fontSize: 12px; }
.header { background-color: #193549; padding: 5px 10px; fontFamily: monospace; color: #ffc600; }
.pre { display: block; padding: 10px 30px; margin: 0; overflow: scroll; }
    </style>

Und ersetzen Sie DebugPrintdurch Folgendes:

const DebugPrint = () => {
  // /programming/30765163/pretty-printing-json-with-react
  const [show, setShow] = React.useState(false);

  return (
    <div key={1} className='root'>
    <div className='header' onClick={ ()=>{setShow(!show)} }>
        <strong>Debug</strong>
    </div>
    { show 
      ? (
      <pre className='pre'>
       {JSON.stringify(data, null, 2) }
      </pre>
      )
      : null
    }
    </div>
  )
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.