Bastante impresión JSON con React


92

Estoy usando ReactJS y parte de mi aplicación requiere JSON bastante impreso.

Obtengo algo de JSON como:, { "foo": 1, "bar": 2 }y si lo ejecuto JSON.stringify(obj, null, 4)en la consola del navegador, se imprime bastante, pero cuando lo uso en este fragmento de reacción:

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

genera JSON bruto que parece "{ \"foo\" : 2, \"bar\": 2}\n".

¿Cómo consigo que esos personajes se interpreten correctamente? {


4
¿Usted ha intentado JSON.stringify(json, null, "\t")?
brroshan

Resulta que tuve un error tonto por el cual this.getStateFromFlux().jsonya estaba devolviendo una cadena. Lo modifiqué para contener un objeto JS en su lugar, y ahora funciona perfectamente.
Brandon

Respuestas:


191

Deberá insertar la BRetiqueta de forma adecuada en la cadena resultante o utilizar, por ejemplo, una PREetiqueta para que se mantenga el formato de stringify:

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'));

Ejemplo de trabajo .

Actualizar

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'));

Ejemplo

Componente funcional sin estado, React .14 o superior

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

O ...

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

Ejemplo de trabajo

Memo / 16.6+

(Es posible que incluso desee utilizar una nota, 16.6+)

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

2
¡Gracias por esto! No sabía sobre el parámetro JSON.stringify-opcional. Javascript es increíble ^^
Marcel Ennix

React ahora está en desuso, use ReactDOM en su lugar
Brane

Esto es perfecto: ¡la solución más simple es siempre la mejor! Recomiendo agregar highlight.js para resaltar la sintaxis y dar un toque de tema.
KeepingItClassy

esto es hermoso
JChao

La solución de etiquetas <pre> funciona perfectamente y esa es la forma correcta.
Vikram K

20

Solo para extender un poco la respuesta de WiredPrairie, un mini componente que se puede abrir y cerrar.

Puede usarse como:

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

ingrese la descripción de la imagen aquí

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>
        );
    }
});

Actualizar

Un enfoque más moderno (ahora que createClass está a punto de desaparecer)

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>
    )
  }
}

Y tu archivo de estilo

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

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

.pre {pantalla: 'bloque'; relleno: '10px 30px'; margen: '0'; desbordamiento: 'desplazamiento'; }


¡Seguro que es un +1 increíble! Hago pequeñas cosas como esta para depurar y probar datos antes de construir el componente en sí. ¡Este es realmente asombroso!
Ryan Hamblin


11

' React-json-view ' proporciona una solución que representa la cadena json.

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>
)

Entonces puedes usarlo fácilmente:

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

0

Aquí hay una demostración react_hooks_debug_print.htmlde react hooks que se basa en la respuesta de Chris. El ejemplo de datos json es de 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>

O de la siguiente manera, agregue el estilo en el encabezado:

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

Y reemplácelo DebugPrintcon lo siguiente:

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>
  )
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.