iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 17
2
Modern Web

TypeScript + React + 雜七雜八系列 第 17

【Day 17】Draft.js,HTML contenteditable 用 React 來控制的 rich text editors

  • 分享至 

  • xImage
  •  

大家好,今天的篇章要介紹的是 Draft.js

會延續前一天的專案結構接續下去進行修改,如果沒有參與到昨天的建置過程,這邊也有提供原始碼
https://github.com/littlehorseboy/typescript-react/tree/day16-react-intl-useintl-usecontext


Draft.js

可以用 React 的 state render 機制來建立 rich text editors,基礎是建立 HTML 的 contenteditable 上,contenteditable 可是在 IE 5.5 時就已經實裝上去了,據說各家瀏覽器實作都有一些差異,Facebook 的團隊就開發出了這款可以弭平瀏覽器實踐 contenteditable 的差異,並且能用 React 的設計思維來操控 contenteditable 所有的內容變化,內容以外的像是滑鼠點擊任意位置時,按鍵控制等等,可能這些操作很一般,draft.js 的 state 就是會通通幫你紀錄下來,就能夠做得到更複雜的編輯器互動

首先就還是先安裝下來

npm i draft-js
npm i -D @types/draft-js

新增一個 component 來簡單的應用一下

第 5 行,一定要使用 draft.js 提供的 EditorState.createEmpty() 來設定初始值

第 7 行,所以 onChange 掛的事件也是傳進 EditorState 型態

所有操作都會環繞著 [editorState, setEditorState] 這個 state

然後要改 Router 相關的設定,讓頁面多長一顆按鈕可以切換顯示 draft.js 的應用

執行結果

當然我們一定要了解看看 EditorState 它的內容到底有什麼變化

來放一個 console.log 用的 Button

第 13 行,editorState.getCurrentContent() 會取回 ContentState,這邊我們就只關心輸出的內容,還有利用 convertToRaw() 這個 draft.js 提供的函數,才能夠 log 出人比較能看得懂的結構

可以看到 text 紀錄著剛剛敲上去的 abc

接著再從頁面上修改一點內容,我要按下一次 Enter 然後輸入 efg

log 觀察看看 ContentState

此時 blocks 就變為兩個內容

筆者會將這些全部轉成 JSON 儲存到某個地方(可能是資料庫),就能從某個地方取回來載入進 Editor

到這邊為止,算是要讓讀者能夠了解修改的 Editor 的內容後,draft.js 為你做的變化,每個動作改變後的內容都會長在這個 ContentState 裡,最後就是把 ContentState 給 JSON.stringfy 儲存到某個地方,就可以直接拿回來載入

讓我來調整一下 DraftJsPractice.tsx 換個方式呈現後說明

這裡我在 useState 時改變了預設值

放了一個 textarea 來將 convertToRaw(editorState.getCurrentContent()) 的內容給扔上去,我想要先直接改動結構中的 text 來改變 ContentState 的內容

與 convertToRaw 相反,使用 convertFromRaw 將 JSON 給 setEditorState

執行結果

改變 Editor 的內容時

改變 textarea 的內容時

到目前為止,應該就能觀察出要如何存取 editorState 的內容,必須要依照 editorState 所需的格式來做轉換,轉換方式就是剛剛的程式碼中用到的那一堆


以上就是筆者在使用 Draft.js 一點小小心得,不過呢,這樣也還不算是編輯器呢,還有那些切換粗體、斜體、改 font-family、font-size、改成超連結,以及增加圖片等等的功能,留待下回揭曉

最後附上原始碼
https://github.com/littlehorseboy/typescript-react/tree/day17-draft-js


明天會繼續介紹 Draft.js 的更多功能,讓它更像一個文字編輯器


上一篇
【Day 16】React Intl,i18n 函式庫,新的 useIntl,實作中還有使用到 useContext
下一篇
【Day 18】Draft.js,用 React 來控制的 rich text editors,再更多功能
系列文
TypeScript + React + 雜七雜八30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言