如何在 React + TypeScript 中實現 JSON 格式化功能

如何在 React + TypeScript 中實現 JSON 格式化功能

作為前端開發者,我們經常需要處理 JSON 數據。無論是 API 調試、配置文件編輯還是數據轉換,能夠格式化 JSON 是一項基本但非常有用的技能。本文將詳細介紹如何在 React 和 TypeScript 環境中實現 JSON 格式化功能,包括基礎知識、實現步驟和最佳實踐。

一、JSON 基礎知識回顧

1.1 什么是 JSON?

JSON(JavaScript Object Notation)是一種輕量級的數據交換格式,易于人閱讀和編寫,同時也易于機器解析和生成。它基于 JavaScript 的一個子集,但獨立于語言,幾乎所有現代編程語言都支持 JSON。

1.2 JSON 的基本結構

JSON 由以下幾種數據類型組成:

  • 對象:無序的鍵值對集合,用花括號 {} 表示
  • 數組:有序的值集合,用方括號 [] 表示
  • 字符串:用雙引號 "" 包裹的文本
  • 數字:整數或浮點數
  • 布爾值:truefalse
  • null:表示空值

1.3 有效的 JSON 示例

{"name": "Alice","age": 25,"isStudent": false,"skills": ["TypeScript", "React", "Node.js"],"address": {"city": "Beijing","postalCode": "100000"}
}

二、JavaScript 中的 JSON 處理方法

JavaScript 提供了兩個內置方法來處理 JSON:

2.1 JSON.parse()

JSON.parse() 方法用于將 JSON 字符串解析為 JavaScript 值或對象。

語法:

JSON.parse(text[, reviver])
  • text: 要解析的 JSON 字符串
  • reviver (可選): 轉換結果的函數,類似于映射函數

示例:

const jsonString = '{"name":"Alice","age":25}';
const obj = JSON.parse(jsonString);
console.log(obj.name); // 輸出: Alice

注意事項:

  • 如果傳入的字符串不是有效的 JSON,JSON.parse() 會拋出 SyntaxError
  • JSON 字符串中的屬性名必須用雙引號 "" 包裹,單引號無效
  • JSON 不支持注釋

2.2 JSON.stringify()

JSON.stringify() 方法用于將 JavaScript 值或對象轉換為 JSON 字符串。

語法:

JSON.stringify(value[, replacer[, space]])
  • value: 要轉換的 JavaScript 值或對象
  • replacer (可選): 用于轉換結果的函數或數組
  • space (可選): 用于縮進的空格數或字符串

示例:

const obj = {name: "Alice", age: 25};
const jsonString = JSON.stringify(obj, null, 2);
console.log(jsonString);
/*
輸出:
{"name": "Alice","age": 25
}
*/

參數詳解:

  • replacer 參數可以是:
    • nullundefined: 不使用替換器
    • 函數: 對每個屬性進行轉換
    • 數組: 指定要包含的屬性名
  • space 參數用于控制縮進:
    • 數字: 表示縮進的空格數(通常 2 或 4)
    • 字符串: 使用該字符串作為縮進(最多 10 個字符)

三、在 React + TypeScript 中實現 JSON 格式化

現在,讓我們實現一個完整的 React + TypeScript 組件,用于格式化用戶輸入的 JSON 字符串。

3.1 創建基本組件結構

首先,我們創建一個基本的 React 組件,包含一個文本區域用于輸入 JSON 和一個顯示格式化結果的文本區域。

import React, { useState } from 'react';
import { Form, Input, Button, notification } from 'antd';const JsonFormatter: React.FC = () => {const [inputJson, setInputJson] = useState<string>('');const [formattedJson, setFormattedJson] = useState<string>('');const handleFormat = () => {try {// 嘗試解析 JSONconst parsed = JSON.parse(inputJson);// 格式化 JSONconst formatted = JSON.stringify(parsed, null, 2);// 更新狀態setFormattedJson(formatted);// 顯示成功通知notification.success({message: 'JSON 格式化成功',});} catch (error) {// 處理錯誤console.error('JSON 解析失敗:', error);notification.error({message: 'JSON 格式錯誤',description: '請輸入有效的 JSON 字符串。',});}};return (<div style={{ padding: '20px' }}><h1>JSON 格式化工具</h1><div style={{ marginBottom: '10px' }}><label htmlFor="jsonInput">輸入 JSON: </label><Input.TextAreaid="jsonInput"value={inputJson}onChange={(e) => setInputJson(e.target.value)}rows={6}style={{ width: '100%' }}/></div><Button type="primary" onClick={handleFormat}>格式化 JSON</Button><div style={{ marginTop: '20px' }}><label>格式化結果: </label><Input.TextAreavalue={formattedJson}rows={6}style={{ width: '100%' }}readOnly/></div></div>);
};export default JsonFormatter;

3.2 使用 Ant Design Form 的實現

如果你已經在項目中使用 Ant Design 的 Form 組件,可以這樣實現:

import React from 'react';
import { Form, Input, Button, notification } from 'antd';interface JsonFormatterFormProps {form: any; // 實際使用時應該使用 FormInstance 類型
}const JsonFormatterForm: React.FC<JsonFormatterFormProps> = ({ form }) => {const handleFormatJson = () => {try {// 獲取表單中的輸入值const input = form.getFieldValue('jsonInput') || '';// 嘗試解析 JSONconst parsed = JSON.parse(input);// 格式化 JSONconst formatted = JSON.stringify(parsed, null, 2);// 設置格式化后的值到表單form.setFieldsValue({ jsonOutput: formatted });// 顯示成功通知notification.success({message: 'JSON 格式化成功',});} catch (error) {// 處理錯誤console.error('JSON 解析失敗:', error);notification.error({message: 'JSON 格式錯誤',description: '請輸入有效的 JSON 字符串。',});}};return (<Form form={form}><Form.Item name="jsonInput" label="輸入 JSON"><Input.TextArea rows={6} /></Form.Item><Button type="primary" onClick={handleFormatJson}>格式化 JSON</Button><Form.Item name="jsonOutput" label="格式化結果"><Input.TextArea rows={6} readOnly /></Form.Item></Form>);
};export default JsonFormatterForm;

3.3 添加高級功能

我們可以進一步增強這個組件,添加一些有用的功能:

  1. 自動檢測并格式化:當用戶停止輸入一段時間后自動格式化
  2. 復制到剪貼板:添加一個按鈕將格式化后的 JSON 復制到剪貼板
  3. 支持 JSON 注釋:使用第三方庫處理帶注釋的 JSON
3.3.1 自動檢測并格式化
import React, { useState, useEffect } from 'react';
import { Form, Input, Button, notification } from 'antd';const JsonFormatterWithAutoFormat: React.FC = () => {const [inputJson, setInputJson] = useState<string>('');const [formattedJson, setFormattedJson] = useState<string>('');const [typingTimeout, setTypingTimeout] = useState<number | null>(null);const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {const value = e.target.value;setInputJson(value);// 清除之前的定時器if (typingTimeout) {clearTimeout(typingTimeout);}// 設置新的定時器,300ms 后執行格式化const timeoutId = window.setTimeout(() => {formatJson(value);}, 300);setTypingTimeout(timeoutId);};const formatJson = (jsonString: string) => {try {const parsed = JSON.parse(jsonString);const formatted = JSON.stringify(parsed, null, 2);setFormattedJson(formatted);notification.success({message: 'JSON 格式化成功',});} catch (error) {// 輸入過程中允許有錯誤,不顯示通知setFormattedJson(''); // 清空結果}};// 組件卸載時清除定時器useEffect(() => {return () => {if (typingTimeout) {clearTimeout(typingTimeout);}};}, [typingTimeout]);return (<div style={{ padding: '20px' }}><h1>JSON 格式化工具 (自動)</h1><div style={{ marginBottom: '10px' }}><label htmlFor="jsonInput">輸入 JSON: </label><Input.TextAreaid="jsonInput"value={inputJson}onChange={handleInputChange}rows={6}style={{ width: '100%' }}/></div><div style={{ marginTop: '20px' }}><label>格式化結果: </label><Input.TextAreavalue={formattedJson}rows={6}style={{ width: '100%' }}readOnly/></div></div>);
};export default JsonFormatterWithAutoFormat;
3.3.2 復制到剪貼板功能
import React, { useState } from 'react';
import { Form, Input, Button, notification } from 'antd';const JsonFormatterWithCopy: React.FC = () => {const [inputJson, setInputJson] = useState<string>('');const [formattedJson, setFormattedJson] = useState<string>('');const handleFormat = () => {try {const parsed = JSON.parse(inputJson);const formatted = JSON.stringify(parsed, null, 2);setFormattedJson(formatted);notification.success({message: 'JSON 格式化成功',});} catch (error) {notification.error({message: 'JSON 格式錯誤',description: '請輸入有效的 JSON 字符串。',});}};const handleCopy = () => {if (!formattedJson) {notification.warning({message: '沒有可復制的內容',});return;}navigator.clipboard.writeText(formattedJson).then(() => {notification.success({message: '已復制到剪貼板',});}).catch(err => {console.error('復制失敗:', err);notification.error({message: '復制失敗',description: '請手動復制或檢查瀏覽器權限。',});});};return (<div style={{ padding: '20px' }}><h1>JSON 格式化工具 (帶復制功能)</h1><div style={{ marginBottom: '10px' }}><label htmlFor="jsonInput">輸入 JSON: </label><Input.TextAreaid="jsonInput"value={inputJson}onChange={(e) => setInputJson(e.target.value)}rows={6}style={{ width: '100%' }}/></div><Button type="primary" onClick={handleFormat} style={{ marginRight: '10px' }}>格式化 JSON</Button><Button onClick={handleCopy} disabled={!formattedJson}>復制到剪貼板</Button><div style={{ marginTop: '20px' }}><label>格式化結果: </label><Input.TextAreavalue={formattedJson}rows={6}style={{ width: '100%' }}readOnly/></div></div>);
};export default JsonFormatterWithCopy;

四、錯誤處理和邊界情況

在實現 JSON 格式化功能時,我們需要考慮各種可能的錯誤情況和邊界條件。

4.1 常見的 JSON 格式錯誤

  1. 缺少引號:JSON 屬性名必須用雙引號包裹

    • 錯誤示例: {name: "Alice"}
    • 正確示例: {"name": "Alice"}
  2. 尾隨逗號:對象或數組最后一項不能有逗號

    • 錯誤示例: {"a": 1, "b": 2,}
    • 正確示例: {"a": 1, "b": 2}
  3. 單引號:JSON 必須使用雙引號,單引號無效

    • 錯誤示例: {'name': 'Alice'}
    • 正確示例: {"name": "Alice"}
  4. 注釋:標準 JSON 不支持注釋

    • 錯誤示例: {"name": "Alice" /* 注釋 */}
    • 正確示例: {"name": "Alice"}

4.2 增強錯誤處理

我們可以改進錯誤處理,提供更具體的錯誤信息:

const handleFormat = () => {if (!inputJson.trim()) {notification.warning({message: '輸入為空',description: '請輸入 JSON 字符串。',});return;}try {const parsed = JSON.parse(inputJson);const formatted = JSON.stringify(parsed, null, 2);setFormattedJson(formatted);notification.success({message: 'JSON 格式化成功',});} catch (error) {if (error instanceof SyntaxError) {notification.error({message: 'JSON 語法錯誤',description: error.message,});} else {notification.error({message: '未知錯誤',description: '發生未知錯誤,請檢查輸入。',});}console.error('JSON 解析失敗:', error);}
};

五、性能優化考慮

對于大型 JSON 文件,格式化操作可能會消耗較多資源,影響用戶體驗。以下是一些性能優化建議:

  1. 限制輸入大小:設置最大輸入字符數,防止用戶粘貼過大的 JSON 文件
  2. Web Worker:將 JSON 解析和格式化操作放到 Web Worker 中執行,避免阻塞主線程
  3. 分塊處理:對于非常大的 JSON 文件,可以考慮分塊處理
  4. 進度指示:長時間操作時顯示進度指示器

5.1 限制輸入大小的實現

const MAX_JSON_SIZE = 100000; // 100KBconst handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {const value = e.target.value;if (value.length > MAX_JSON_SIZE) {notification.warning({message: '輸入過大',description: `JSON 輸入不能超過 ${MAX_JSON_SIZE / 1000}KB`,});return;}setInputJson(value);// ...其余代碼不變
};

六、總結

在本文中,我們詳細介紹了如何在 React 和 TypeScript 環境中實現 JSON 格式化功能。我們從 JSON 的基礎知識開始,回顧了 JavaScript 中的 JSON.parse()JSON.stringify() 方法,然后逐步構建了一個完整的 React 組件,實現了以下功能:

  1. 基本的 JSON 格式化功能
  2. 完善的錯誤處理和用戶反饋
  3. 自動檢測和格式化
  4. 復制到剪貼板功能
  5. 性能優化考慮

這個功能雖然簡單,但在實際開發中非常實用,無論是作為獨立的工具組件還是集成到更大的應用中。通過這個例子,我們不僅學習了如何處理 JSON 數據,還實踐了 React 和 TypeScript 的最佳實踐,包括狀態管理、錯誤處理和用戶體驗優化。


推薦更多閱讀內容
程序員視角:第三方風險管理那些事兒
程序員視角:為什么攻擊后企業總愛“裝死”?我們能做點啥?
大語言模型(LLM)來了,程序員該怎么應對安全問題?
AI 生成的經典貪吃蛇小游戲
普通職場人如何理解AI安全?從五個關鍵問題說起
瀏覽器存儲機制對比(cookie、localStorage、sessionStorage)
Cookie的HttpOnly屬性:作用、配置與前后端分工
從威脅檢測需求看兩類安全監測平臺差異
深入理解JavaScript數組過濾操作(提升代碼優雅性)
JavaScript 數組合并與去重(解析 […value, …ids] 技巧)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/89501.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/89501.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/89501.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Mac連接服務器Docker容器全攻略

蘋果電腦( macOS 系統 )連接服務器、配置容器,整體思路和 Linux 終端操作更貼近,以下結合 macOS 特點,詳細分步說明,以 Docker 容器 + 常見 Linux 服務器( 如 CentOS、Ubuntu )為例: 一、連接服務器(SSH 方式, macOS 終端原生支持 ) 1. 準備信息 找運維或云平臺…

【字節跳動】數據挖掘面試題0019:帶貨直播間推薦:現在有一個帶貨的直播間,怎么把它精準地推送給有需要的用戶

文章大綱 帶貨直播間推薦系統:原理、算法與實踐 一、推薦系統在帶貨直播中的重要性 二、數據收集與處理 1. 用戶數據 2. 直播間數據 3. 用戶行為數據 4. 數據處理與特征工程 三、推薦算法實現 1. 基于內容的推薦 2. 基于協同過濾的推薦 3. 基于知識圖譜的推薦 4. 混合推薦算法…

Windows10筆記本電腦開啟BIOS

文章目錄什么是BIOS一、方案一&#xff1a;快捷鍵進入二、方案二&#xff08;推薦&#xff09;各品牌快捷鍵大全什么是BIOS BIOS 全拼為 BasicInputOutputSystem, 即基本輸入/輸出系統,是計算機中非常基礎而且重要的程序。把這一段程序存放在一個不需要電源的記憶體(芯片)中,就…

NFS、iSCSI 和lnmp部署操作

目錄 &#xff08;一&#xff09;基礎配置 1.NFS服務安裝 2.修改配置文件 3.重載配置文件 4.查看共享目錄 5.客戶端掛載 6.更換共享目錄 7.基礎實驗 &#xff08;二&#xff09;布置lnmp平臺 1.php 安裝軟件 檢測 2.連接MySQL 測試 3.軟件實施 軟件安裝配置 &…

Redis深度解析:從緩存原理到高并發實戰

第一部分&#xff1a;Redis核心概念與架構設計1.1 Redis本質解析Redis&#xff08;Remote Dictionary Server&#xff09;作為開源的內存數據結構存儲系統&#xff0c;其核心價值在于&#xff1a;內存優先架構&#xff1a;數據主要存儲在內存中&#xff0c;讀寫性能達到10萬 QP…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - 微博類別信息爬取

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解架構搭建 視頻在線地址&#xff1a; 2026…

GD32/STM32嵌入CMSIS-DSP的庫(基于Keil)

當你要用到三角函數、開方、矩陣運算等復雜的數學運算時&#xff0c;可以選擇用C庫的math.h里面的函數&#xff0c;如果要求速度快的話就得用CMSIS-DSP庫里面的函數了&#xff0c;因為CMSIS-DSP庫充分運用了CM4內核的浮點運算單元&#xff08;若有&#xff09;和DSP相關的指令&…

頁面登錄阻止瀏覽器提醒是否保存密碼

一、原因 使用input的type"password"類型&#xff0c;瀏覽器會提醒是否記住密碼。 二、解決 取消type"password" 三、實現輸入密碼*代替 通過input輸入框&#xff0c;監聽輸入值&#xff0c;進行替換成*符號&#xff0c;避免使用input的type"password…

【iOS】dyld加載流程——應用程序的加載

目錄 前言 編譯過程與動靜態庫 編譯過程 動靜態庫 dyld &#x1f4cc; 什么是 dyld&#xff1f; dyld_shared_cache: dyld加載流程 _dyld_start dyldbootstrap::start dyld::main() 配置環境變量 共享緩存 主程序的初始化 插入動態庫 link主程序 link動態庫 弱…

從零開始,手把手教你本地部署Stable Diffusion AI繪畫(Win最新版)

本號之前有發過一篇win平臺的教程&#xff0c;由于是去年10月發布的&#xff0c;而Al繪畫技術發展很快&#xff0c;那篇教程已經有些不適用了&#xff0c;有些同學執行到第二步就出錯了。 應廣大同學的期望&#xff0c;我更新一版新版詳細教程。 一、前言 1.為什么要本地部署…

day21 力扣669. 修剪二叉搜索樹 力扣108.將有序數組轉換為二叉搜索樹 力扣538.把二叉搜索樹轉換為累加樹

修剪二叉搜索樹 給你二叉搜索樹的根節點 root &#xff0c;同時給定最小邊界low 和最大邊界 high。通過修剪二叉搜索樹&#xff0c;使得所有節點的值在[low, high]中。修剪樹 不應該 改變保留在樹中的元素的相對結構 (即&#xff0c;如果沒有被移除&#xff0c;原有的父代子代關…

《設計模式之禪》筆記摘錄 - 7.中介者模式

中介者模式的定義中介者模式的定義為&#xff1a;Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently…

Flutter:上傳圖片,選擇相機或相冊:wechat_assets_picker

圖片選擇功能&#xff1a;可選單張&#xff0c;或多張。 1、showModalBottomSheet&#xff08;選擇相冊/相機&#xff09; 2、WechatImagePicker&#xff08;選取圖片&#xff09; 3、CompressMediaFile&#xff08;圖片壓縮&#xff09;1、ActionSheetUtilimport package:duca…

pytest--0

1 pytest 使用方式 pytest測試框架-- 基本功能使用詳解 2 pytest-mock常用方式 pytest–1–pytest-mock常用的方法 3

multiprocessing.Pool 中的 pickle 詳解

前言&#xff1a; 在 Python 的 multiprocessing.Pool 中&#xff0c;任務和數據需要通過序列化&#xff08;pickle&#xff09;傳遞給子進程。pickle 是 Python 的內置序列化模塊&#xff0c;用于將 Python 對象轉換為字節流&#xff0c;以便在進程間通信時傳遞。然而&#xf…

Java集合框架體系詳解:List/Set/Map接口對比與核心實現原理

一、集合框架核心接口對比 1.1 List/Set/Map接口特性接口類型特性描述典型實現List有序可重復&#xff0c;支持索引訪問ArrayList/LinkedListSet無序不可重復&#xff0c;基于哈希表或樹實現HashSet/TreeSetMap鍵值對存儲&#xff0c;鍵唯一值可重復HashMap/TreeMap核心差異&am…

LeafletJS 進階:GeoJSON 與動態數據可視化

引言 LeafletJS 作為一個輕量、靈活的 JavaScript 地圖庫&#xff0c;以其對 GeoJSON 數據格式的強大支持而聞名。GeoJSON 是一種基于 JSON 的地理數據格式&#xff0c;能夠表示點&#xff08;Point&#xff09;、線&#xff08;LineString&#xff09;、多邊形&#xff08;Po…

【STM32實踐篇】:F407 時鐘系統

文章目錄1. 時鐘與啟動2. CubeMX 時鐘樹2.1 時鐘源2.2 PLL 鎖相環2.3 時鐘分發與選擇2.4 頻率限制1. 時鐘與啟動 復位默認時鐘&#xff1a;系統復位后&#xff0c;CPU 時鐘默認由 16MHz 內部 RC 振蕩器&#xff08;HSI&#xff09;提供&#xff0c;該 RC 振蕩器經工廠校準&…

純前端html實現圖片坐標與尺寸(XY坐標及寬高)獲取

純前端html實現圖片坐標與尺寸&#xff08;XY坐標及寬高&#xff09;獲取。用于證書圖片或pdf打印的坐標測定。 <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <title>純html前端實現圖片坐標與尺寸&am…

飛睿UWB超寬帶定位測距技術,數字鑰匙重塑智能生活,高精度厘米級定位無感解鎖

最近&#xff0c;數字鑰匙領域動作頻頻&#xff0c;科技巨頭與車企正掀起一波創新浪潮。小米15S Pro搭載恩智浦UWB芯片&#xff0c;用戶靠近閘機即可無感通行深圳云巴一號線&#xff0c;輕觸小米YU7車門自動解鎖&#xff0c;實現手機-汽車-公共交通的無縫數字鑰匙生態。在智能家…