潮起云生 发表于 2024-7-5 21:20:34

react-json-editor-ajrm解析错误与解决方案

背景

由于历史原因,项目中 JSON 编辑器使用的是 react-json-editor-ajrm,近期遇到一个严重的展示错误,传入编辑器的数据与展示的不一致,这是产品和用户不可接受的。


工具介绍

react-json-editor-ajrm 可以用于查看、编辑和校验 JSON 对象。但这个项目已经不再积极维护,并计划在2023年6月15日废弃。
<a href="https://github.com/AndrewRedican/react-json-editor-ajrm" rel="external nofollow"rel="external nofollow"   target="_blank">https://github.com/AndrewRedican/react-json-editor-ajrm</a><strong>Warning:</strong> As you may already know, the react-json-editor-ajrm's orignal project is not actively maintained and that it will eventually <strong>be deprecated</strong>. So I've decided to set an official date for deprecation. The tentative date for this is June 15, 2023.
问题复现

使用官方示例
<a href="https://github.com/AndrewRedican/react-json-editor-ajrm/blob/master/example/create-react-app-project/src/index.js" rel="external nofollow"   target="_blank">https://github.com/AndrewRedican/react-json-editor-ajrm/blob/master/example/create-react-app-project/src/index.js</a>这里仅把测试数据换成能复现问题的数据(在解析嵌套带引号数据时会出问题)
export const testData = {
"key1": "{"test":"{\"name\":\"editor\"}"}",
"key2": "{"name":"editor"}",
"key3": {
    "name": "editor"
}
}import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./index.css";

import JSONInput from "react-json-editor-ajrm/index";
import locale from "react-json-editor-ajrm/locale/en";

import { testData } from "./testData";

class App extends Component {
render() {
    /**
   * Rendering this JSONInput component with some properties
   */
    return (
      <div style={{ maxWidth: "1400px", maxHeight: "100%" }}>
      <JSONInput
          placeholder={testData} // data to display
          theme="light_mitsuketa_tribute"
          locale={locale}
          colors={{
            string: "#DAA520" // overrides theme colors with whatever color value you want
          }}
          height="550px"
          onChange={(e) => {
            console.log("jsoneditor-onchange-e", e);
          }}
      />
      </div>
    );
}
}

ReactDOM.render(<App />, document.querySelector("#root"));渲染效果如图:


很明显能看出问题,key1、key2 的展示都跟原始数据不一致

探究原因

这是用一个常用的 JSON 格式化工具的展示效果。证明数据是没问题的,而是 react-json-editor-ajrm 内部处理逻辑导致的问题。

深入分析 react-json-editor-ajrm 源码,发现 this.tokenize 函数在处理传入数据时出现了问题。这导致了数据标记(tokens)的生成错误,进一步导致 markupText 的错误,最终影响了数据的展示。

分析链路


[*]render 函数中,dangerouslySetInnerHTML: this.createMarkup(markupText)


[*]showPlaceholder 函数中
const data = this.tokenize(placeholder);
    this.setState({
      prevPlaceholder: placeholder,
      plainText: data.indentation,
      markupText: data.markup,
      lines: data.lines,
      error: data.error
    });

[*]placeholder 是传入的数据
[*]markupText 取自 this.tokenize(placeholder),然后更新


[*]关键在于 this.tokenize 对 placeholder 的处理,这里直接给出 this.tokenize 调用后的结果,感兴趣的可以查看源码

markup
"<span type="symbol" value="{" depth="1" style="color:#D4D4D4">{</span>
<span type="key" value="key1" depth="1" style="color:#59A5D8">key1</span><span type="symbol" value=":" depth="1" style="color:#49B8F7">:</span> <span type="string" value="'{'" depth="1" style="color:#DAA520">'{'</span><span type="" value="" depth="1" style="color:#D4D4D4"></span><span type="string" value="':'" depth="1" style="color:#DAA520">':'</span><span type="symbol" value="{" depth="2" style="color:#D4D4D4">{</span>
    <span type="key" value="'name\'" depth="2" style="color:#59A5D8">'name\'</span><span type="symbol" value=":" depth="2" style="color:#49B8F7">:</span> <span type="string" value="'editor\'" depth="2" style="color:#DAA520">'editor\'</span>
<span type="symbol" value="}" depth="1" style="color:#D4D4D4">}</span><span type="key" value="'}'" depth="1" style="color:#59A5D8">'}'</span><span type="symbol" value="," depth="1" style="color:#D4D4D4">,</span>
<span type="key" value="key2" depth="1" style="color:#59A5D8">key2</span><span type="symbol" value=":" depth="1" style="color:#49B8F7">:</span> <span type="string" value="'{'" depth="1" style="color:#DAA520">'{'</span><span type="" value="" depth="1" style="color:#D4D4D4"></span><span type="string" value="':'" depth="1" style="color:#DAA520">':'</span><span type="" value="" depth="1" style="color:#D4D4D4"></span><span type="string" value="'}'" depth="1" style="color:#DAA520">'}'</span><span type="symbol" value="," depth="1" style="color:#D4D4D4">,</span>
<span type="key" value="key3" depth="1" style="color:#59A5D8">key3</span><span type="symbol" value=":" depth="1" style="color:#49B8F7">:</span> <span type="symbol" value="{" depth="2" style="color:#D4D4D4">{</span>
    <span type="key" value="name" depth="2" style="color:#59A5D8">name</span><span type="symbol" value=":" depth="2" style="color:#49B8F7">:</span> <span type="string" value="'editor'" depth="2" style="color:#DAA520">'editor'</span>
<span type="symbol" value="}" depth="1" style="color:#D4D4D4">}</span>
<span type="symbol" value="}" depth="0" style="color:#D4D4D4">}</span>"
解决方案

由于这是 react-json-editor-ajrm 内部处理逻辑导致的,所以只能考虑更换依赖包。
调研发现可以使用 jsoneditor-react,这里给出简单的示例:
import { JsonEditor as Editor } from 'jsoneditor-react';
import 'jsoneditor-react/es/editor.min.css';

import React from 'react'
import { testData } from './testData';
function App() {
return (
    <Editor
      value={testData}
      onChange={(val) => {
          console.log("jsoneditor-react-val", val);
      }}
    />
)
}

export default App
项目启动后,发现展示是符合预期的,也没有别的问题,可以使用 jsoneditor-react 作为替换的三方包。

工具对比

react-json-editor-ajrm vs jsoneditor-react

<a href="https://npmtrends.com/jsoneditor-react-vs-react-json-editor-ajrm" rel="external nofollow"   target="_blank">https://npmtrends.com/jsoneditor-react-vs-react-json-editor-ajrm</a>在 npmtrends.com/ 中对两个工具的下载趋势进行了对比
pkg简介star地址react-json-editor-ajrmA stylish, editor-like, modular, react component for viewing, editing, and debugging javascript object syntax!354<a href="https://github.com/AndrewRedican/react-json-editor-ajrm" rel="external nofollow"rel="external nofollow"   target="_blank">https://github.com/AndrewRedican/react-json-editor-ajrm</a>jsoneditor-reactreact wrapper implementation for jsoneditor262https://github.com/vankop/jsoneditor-reactjsoneditor-11.3khttps://github.com/josdejong/jsoneditor虽然从下载量以及 GitHub star 数量来看,jsoneditor-react 并不如 react-json-editor-ajrm,但 jsoneditor-react 是基于 jsoneditor 二次封装的,所以稳定性还是有一定的保障。
以上就是react-json-editor-ajrm解析错误与解决方案的详细内容,更多关于react-json-editor-ajrm错误的资料请关注脚本之家其它相关文章!

来源:https://www.jb51.net/javascript/32350649b.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: react-json-editor-ajrm解析错误与解决方案