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? {

Brandon
quelle
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
1
siehe auch github.com/alexkuz/react-json-tree
Aprillion

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>));
WiredPrairie
quelle
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'; }}

Chris
quelle
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" />
Aborn Jiang
quelle
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>
}
Ben Carp
quelle
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/[email protected]/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>
  )
}
caot
quelle