react-json-editor-ajrm解析錯(cuò)誤與解決方案
背景
由于歷史原因,項(xiàng)目中 JSON 編輯器使用的是 react-json-editor-ajrm,近期遇到一個(gè)嚴(yán)重的展示錯(cuò)誤,傳入編輯器的數(shù)據(jù)與展示的不一致,這是產(chǎn)品和用戶不可接受的。
工具介紹
react-json-editor-ajrm 可以用于查看、編輯和校驗(yàn) JSON 對(duì)象。但這個(gè)項(xiàng)目已經(jīng)不再積極維護(hù),并計(jì)劃在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)
使用官方示例
這里僅把測(cè)試數(shù)據(jù)換成能復(fù)現(xiàn)問題的數(shù)據(jù)(在解析嵌套帶引號(hào)數(shù)據(jù)時(shí)會(huì)出問題)
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ù)不一致
探究原因
這是用一個(gè)常用的 JSON 格式化工具的展示效果。證明數(shù)據(jù)是沒問題的,而是 react-json-editor-ajrm 內(nèi)部處理邏輯導(dǎo)致的問題。
深入分析 react-json-editor-ajrm 源碼,發(fā)現(xiàn) this.tokenize 函數(shù)在處理傳入數(shù)據(jù)時(shí)出現(xiàn)了問題。這導(dǎo)致了數(shù)據(jù)標(biāo)記(tokens)的生成錯(cuò)誤,進(jìn)一步導(dǎo)致 markupText 的錯(cuò)誤,最終影響了數(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 對(duì) 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
項(xiàng)目啟動(dòng)后,發(fā)現(xiàn)展示是符合預(yù)期的,也沒有別的問題,可以使用 jsoneditor-react 作為替換的三方包。
工具對(duì)比
react-json-editor-ajrm vs jsoneditor-react
https://npmtrends.com/jsoneditor-react-vs-react-json-editor-ajrm
在 npmtrends.com/ 中對(duì)兩個(gè)工具的下載趨勢(shì)進(jìn)行了對(duì)比
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解析錯(cuò)誤與解決方案的詳細(xì)內(nèi)容,更多關(guān)于react-json-editor-ajrm錯(cuò)誤的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解React 在服務(wù)端渲染的實(shí)現(xiàn)
這篇文章主要介紹了詳解React 在服務(wù)端渲染的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11React+TS+IntersectionObserver實(shí)現(xiàn)視頻懶加載和自動(dòng)播放功能
通過本文的介紹,我們學(xué)習(xí)了如何使用 React + TypeScript 和 IntersectionObserver API 來實(shí)現(xiàn)一個(gè)視頻播放控制組件,該組件具有懶加載功能,只有在用戶滾動(dòng)頁面且視頻進(jìn)入視口時(shí)才開始下載視頻資源,需要的朋友可以參考下2023-04-04React組件創(chuàng)建與事件綁定的實(shí)現(xiàn)方法
react事件綁定時(shí)。this并不會(huì)指向當(dāng)前DOM元素。往往使用bind來改變this指向,今天通過本文給大家介紹React事件綁定的方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-12-12React 數(shù)據(jù)獲取與性能優(yōu)化詳解
這篇文章主要為大家介紹了React 數(shù)據(jù)獲取與性能優(yōu)化方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10React中使用async validator進(jìn)行表單驗(yàn)證的實(shí)例代碼
react上進(jìn)行表單驗(yàn)證是很繁瑣的,在這里使用async-validator處理起來就變的很方便了,接下來通過本文給大家介紹React中使用async validator進(jìn)行表單驗(yàn)證的方法,需要的朋友可以參考下2018-08-08