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

 更新时间:2024年06月30日 09:31:15   作者:窗边的anini  
由于历史原因,项目中 JSON 编辑器使用的是 react-json-editor-ajrm,近期遇到一个严重的展示错误,传入编辑器的数据与展示的不一致,这是产品和用户不可接受的,本文给大家介绍了react-json-editor-ajrm解析错误与解决方案,需要的朋友可以参考下

背景

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

工具介绍

react-json-editor-ajrm 可以用于查看、编辑和校验 JSON 对象。但这个项目已经不再积极维护,并计划在2023年6月15日废弃。

https://github.com/AndrewRedican/react-json-editor-ajrm

Warning: As you may already know, the react-json-editor-ajrm's orignal project is not actively maintained and that it will eventually be deprecated. So I've decided to set an official date for deprecation. The tentative date for this is June 15, 2023.

问题复现

使用官方示例

https://github.com/AndrewRedican/react-json-editor-ajrm/blob/master/example/create-react-app-project/src/index.js

这里仅把测试数据换成能复现问题的数据(在解析嵌套带引号数据时会出问题)

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

https://npmtrends.com/jsoneditor-react-vs-react-json-editor-ajrm

npmtrends.com/ 中对两个工具的下载趋势进行了对比

pkg简介star地址
react-json-editor-ajrmA stylish, editor-like, modular, react component for viewing, editing, and debugging javascript object syntax!354https://github.com/AndrewRedican/react-json-editor-ajrm
jsoneditor-reactreact wrapper implementation for jsoneditor262https://github.com/vankop/jsoneditor-react
jsoneditor-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错误的资料请关注脚本之家其它相关文章!

相关文章

  • 一文带你深入理解React中的Context

    一文带你深入理解React中的Context

    React Context是React提供给开发者的一种常用的状态管理机制,本文主要来和大家讲讲为什么需要Context,又是如何使用Context的,感兴趣的可以了解一下
    2023-05-05
  • 详解React自定义Hook

    详解React自定义Hook

    在React项目中,我们经常会使用到React自带的几个内置Hooks,如 useState,useContext和useEffect。虽然在React中找不到这些 Hooks,但React提供了非常灵活的方式让你为自己的需求来创建自己的自定义Hooks,想了解更多的,欢迎阅读本文
    2023-04-04
  • 详解React 在服务端渲染的实现

    详解React 在服务端渲染的实现

    这篇文章主要介绍了详解React 在服务端渲染的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • React中的Hooks路由跳转问题

    React中的Hooks路由跳转问题

    这篇文章主要介绍了React中的Hooks路由跳转问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • React 小技巧教你如何摆脱hooks依赖烦恼

    React 小技巧教你如何摆脱hooks依赖烦恼

    Hooks 是一种函数,该函数允许您从函数式组件 “勾住(hook into)” React 状态和生命周期功能。 Hooks 在类内部不起作用 - 它们允许你无需类就使用 React,本文带领大家学习React 小技巧教你如何摆脱hooks依赖烦恼,感兴趣的朋友一起看看吧
    2021-05-05
  • React+TS+IntersectionObserver实现视频懒加载和自动播放功能

    React+TS+IntersectionObserver实现视频懒加载和自动播放功能

    通过本文的介绍,我们学习了如何使用 React + TypeScript 和 IntersectionObserver API 来实现一个视频播放控制组件,该组件具有懒加载功能,只有在用户滚动页面且视频进入视口时才开始下载视频资源,需要的朋友可以参考下
    2023-04-04
  • React中useEffect函数的使用详解

    React中useEffect函数的使用详解

    useEffect是React中的一个钩子函数,用于处理副作用操作,这篇文章主要为大家介绍了React中useEffect函数的具体用法,希望对大家有所帮助
    2023-08-08
  • React组件创建与事件绑定的实现方法

    React组件创建与事件绑定的实现方法

    react事件绑定时。this并不会指向当前DOM元素。往往使用bind来改变this指向,今天通过本文给大家介绍React事件绑定的方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • React 数据获取与性能优化详解

    React 数据获取与性能优化详解

    这篇文章主要为大家介绍了React 数据获取与性能优化方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • React中使用async validator进行表单验证的实例代码

    React中使用async validator进行表单验证的实例代码

    react上进行表单验证是很繁琐的,在这里使用async-validator处理起来就变的很方便了,接下来通过本文给大家介绍React中使用async validator进行表单验证的方法,需要的朋友可以参考下
    2018-08-08

最新评论