react-json-editor-ajrm解析錯誤與解決方案
背景
由于歷史原因,項目中 JSON 編輯器使用的是 react-json-editor-ajrm,近期遇到一個嚴(yán)重的展示錯誤,傳入編輯器的數(shù)據(jù)與展示的不一致,這是產(chǎn)品和用戶不可接受的。

工具介紹
react-json-editor-ajrm 可以用于查看、編輯和校驗 JSON 對象。但這個項目已經(jīng)不再積極維護(hù),并計劃在2023年6月15日廢棄。
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.
問題復(fù)現(xiàn)
使用官方示例
這里僅把測試數(shù)據(jù)換成能復(fù)現(xiàn)問題的數(shù)據(jù)(在解析嵌套帶引號數(shù)據(jù)時會出問題)
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 的展示都跟原始數(shù)據(jù)不一致
探究原因
這是用一個常用的 JSON 格式化工具的展示效果。證明數(shù)據(jù)是沒問題的,而是 react-json-editor-ajrm 內(nèi)部處理邏輯導(dǎo)致的問題。

深入分析 react-json-editor-ajrm 源碼,發(fā)現(xiàn) this.tokenize 函數(shù)在處理傳入數(shù)據(jù)時出現(xiàn)了問題。這導(dǎo)致了數(shù)據(jù)標(biāo)記(tokens)的生成錯誤,進(jìn)一步導(dǎo)致 markupText 的錯誤,最終影響了數(shù)據(jù)的展示。
分析鏈路
- render 函數(shù)中,dangerouslySetInnerHTML: this.createMarkup(markupText)

- showPlaceholder 函數(shù)中
const data = this.tokenize(placeholder);
this.setState({
prevPlaceholder: placeholder,
plainText: data.indentation,
markupText: data.markup,
lines: data.lines,
error: data.error
});
- placeholder 是傳入的數(shù)據(jù)
- markupText 取自 this.tokenize(placeholder),然后更新
- 關(guān)鍵在于 this.tokenize 對 placeholder 的處理,這里直接給出 this.tokenize 調(diào)用后的結(jié)果,感興趣的可以查看源碼

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 內(nèi)部處理邏輯導(dǎo)致的,所以只能考慮更換依賴包。
調(diào)研發(fā)現(xiàn)可以使用 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

項目啟動后,發(fā)現(xiàn)展示是符合預(yù)期的,也沒有別的問題,可以使用 jsoneditor-react 作為替換的三方包。
工具對比
react-json-editor-ajrm vs jsoneditor-react

https://npmtrends.com/jsoneditor-react-vs-react-json-editor-ajrm
在 npmtrends.com/ 中對兩個工具的下載趨勢進(jìn)行了對比
| pkg | 簡介 | star | 地址 |
|---|---|---|---|
| react-json-editor-ajrm | A stylish, editor-like, modular, react component for viewing, editing, and debugging javascript object syntax! | 354 | https://github.com/AndrewRedican/react-json-editor-ajrm |
| jsoneditor-react | react wrapper implementation for jsoneditor | 262 | https://github.com/vankop/jsoneditor-react |
| jsoneditor | - | 11.3k | https://github.com/josdejong/jsoneditor |
雖然從下載量以及 GitHub star 數(shù)量來看,jsoneditor-react 并不如 react-json-editor-ajrm,但 jsoneditor-react 是基于 jsoneditor 二次封裝的,所以穩(wěn)定性還是有一定的保障。
以上就是react-json-editor-ajrm解析錯誤與解決方案的詳細(xì)內(nèi)容,更多關(guān)于react-json-editor-ajrm錯誤的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React調(diào)度系統(tǒng)Scheduler工作原理詳解
這篇文章主要為大家介紹了React調(diào)度系統(tǒng)Scheduler工作原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
解決React報錯Cannot?find?namespace?context
這篇文章主要為大家介紹了React報錯Cannot?find?namespace?context分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
React生命周期與父子組件間通信知識點(diǎn)詳細(xì)講解
生命周期函數(shù)指在某一時刻組件會自動調(diào)用并執(zhí)行的函數(shù)。React每個類組件都包含生命周期方法,以便于在運(yùn)行過程中特定的階段執(zhí)行這些方法2022-11-11
React 中更新隊列 updateQueue的實現(xiàn)示例
本文主要介紹了React 中更新隊列 updateQueue的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-05-05
React.memo函數(shù)中的參數(shù)示例詳解
這篇文章主要為大家介紹了React.memo函數(shù)中的參數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
React-Native左右聯(lián)動List的示例代碼
本篇文章主要介紹了React-Native左右聯(lián)動List的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09

