【问题标题】:Pretty Printing JSON with React使用 React 漂亮地打印 JSON
【发布时间】:2015-08-26 05:25:39
【问题描述】:

我正在使用 ReactJS,我的部分应用程序需要打印精美的 JSON。

我得到一些 JSON,例如:{ "foo": 1, "bar": 2 },如果我在浏览器控制台中通过 JSON.stringify(obj, null, 4) 运行它,它会打印得很漂亮,但是当我在这个反应 sn-p 中使用它时:

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

它呈现看起来像"{ \"foo\" : 2, \"bar\": 2}\n" 的粗略 JSON。

如何正确解释这些字符? {

【问题讨论】:

  • 你试过JSON.stringify(json, null, "\t")吗?
  • 原来我遇到了一个愚蠢的错误,this.getStateFromFlux().json 已经返回了一个字符串。我将其修改为保存一个 JS 对象,现在它可以完美运行。

标签: javascript json reactjs flux


【解决方案1】:

您需要在结果字符串中适当地插入 BR 标记,或者使用例如 PRE 标记以便保留 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'));

Working example.

更新

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

无状态功能组件,React .14 或更高版本

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

或者,...

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

Working example

备忘录 / 16.6+

(您甚至可能想要使用备忘录,16.6+)

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

【讨论】:

  • 谢谢!不知道可选的 JSON.stringify 参数。 Javascript很棒^^
  • 这是完美的——最简单的解决方案永远是最好的!我建议添加 highlight.js 以进行语法高亮和主题化。
  • 这很漂亮
  •  标签解决方案完美运行,这是正确的方法!
  • 太好了,正是我想要的:)
【解决方案2】:

只是为了扩展 WiredPrairie 的回答,一个可以打开和关闭的迷你组件。

可以这样使用:

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

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

更新

一种更现代的方法(现在 createClass 即将淘汰)

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

还有你的样式文件

.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';
}

【讨论】:

【解决方案3】:

'react-json-view'提供解决方案渲染json字符串。

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

【讨论】:

    【解决方案4】:
    const getJsonIndented = (obj) => JSON.stringify(newObj, null, 4).replace(/["{[,\}\]]/g, "")
    
    const JSONDisplayer = ({children}) => (
        <div>
            <pre>{getJsonIndented(children)}</pre>
        </div>
    )
    

    那么你就可以轻松使用了:

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

    【讨论】:

      【解决方案5】:

      TLDR

      React 中的漂亮打印 JSON

      <pre>{JSON.stringify(data, null, 2)}</pre>
      

      【讨论】:

      • 简单是关键。谢谢!
      【解决方案6】:

      简短而简单

      <div>
        <pre dangerouslySetInnerHTML={{
           __html: JSON.stringify(data, null, 2),
        }} />
      </div>
      

      【讨论】:

        【解决方案7】:

        这是一个基于 Chris 回答的反应钩子中的演示 react_hooks_debug_print.html。 json数据示例来自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>
        
        

        或者通过以下方式,将样式添加到header中:

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

        并将DebugPrint 替换为以下内容:

        const DebugPrint = () => {
          // https://stackoverflow.com/questions/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>
          )
        }
        

        【讨论】:

          猜你喜欢
          • 2015-07-03
          • 2023-04-04
          • 2013-10-03
          • 2011-08-05
          相关资源
          最近更新 更多