筆記 React.js 中 useMemo Hook

前言 暑假回去公司實習時把 React 文件拿出來重新複習一次,順便在一些可以優化的地方使用 useMemo, useCallback,順手做個紀錄。 被計算出來的狀態使用 useMemo 範例:計算按鈕何時應啟用 disabled 樣式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // Before: 自己寫 useEffect 去監聽依賴,在依賴變動時重新賦值 const [input, setInput] = useState('') const [isInputError, setIsInputError] = useState(false) const [isBtnDisabled, setIsBtnDisabled] = useState(true) useEffect(() => { setIsBtnDisabled(input === '' || isInputError) }, [input, isInputError]) // ------------------------------------------------------ // After: 使用 useMemo const [input, setInput] = useState('') const [isInputError, setIsInputError] = useState(false) const isBtnDisabled = useMemo(() => { return (input === '' || isInputError) }, [input, isInputError]) useMemo 也可以 memorize 一個 functional component...

July 29, 2021

用同理心提升使用者體驗

前言 我在上大學前的程式經驗只有程式競賽,到了大二才開始走進軟體開發,那時對於打造使用者介面有許多的憧憬而一頭栽進了前端開發的世界。 在跟同學合作的許多 side projects 中我時常負責前端,在外頭的世界除了工程師,要創造有價值的產品還需要一個相當重要的角色———設計師,而我們這群忙著寫程式的資工系小鬼頭哪有人跳出來擔當設計師呢?於是 UI, UX 的責任通常就落到寫前端的人身上(苦笑)。 雖然講得一副很委屈的樣子,但在過程中我開始著迷於研究如何做好 UI, UX,我覺得對於使用者來說,UI, UX 幾乎代表了前端的所有價值,哪個使用者會在乎你用了什麼很潮的技術或框架,或你的程式碼乾淨又美麗呢? 總之,我想藉著這篇文章來記錄寫前端的這些時日,從一位工程師的角度是怎麼感受使用者體驗的問題。 任何人都會碰到痛點 不是每個人都有設計的天賦,但是每個人都會感受到痛。 你是否曾在寫程式時用了其他人寫的 Library,結果一邊寫一邊心裡想「X!這個 API 怎麼設計的這麼糟糕?」或在疫情期間進到每一家店都要填寫各種獨家設計的實名制表單?學校的某某系統好難用?說明書有看沒有懂?在百貨公司繞了半圈找不到廁所? 這些讓你覺得「怎麼這麼蠢」的時刻,常常就是使用者體驗很糟的地方。 上面的痛點你遇過幾個呢?很遺憾但也很慶幸生活中有這麼多不如意的事情,因為這些反例往往可以當作借鏡,去審視自己創造出來的東西。 我在一開始設計前端時也是從模仿開始,除了可以從其他地方參考到好的設計,不好的設計讓我們避免重蹈覆轍,減少使用者的痛點。 開發者也有很多時候在當使用者,我們使用 IDE、開發時使用第三方工具或框架、程式碼架構引入 Design Pattern,都是希望能讓開發者的體驗更好。 解決需求並不容易 講到這些增進開發者體驗的工具,我們不妨回頭來想他們為什麼會被創造出來? 例如撰寫 JavaScript 應用的開發者為何會選擇採用 TypeScript 呢?也許是希望在撰寫大型專案時可以有靜態型別檢查,結合其他工具產生基本的文件等等。或是引入 Design Pattern 的開發者希望可以解決一個他在程式碼中看到的問題。 這些工具解決了開發者的需求,但事實上,十全十美的解法並不多,我們都知道有時候採用一些工具或方法會帶來副作用,也因此我們知道要衡量利弊,要做 trade-off。 我初期在前端設計常犯的一個錯誤,就是我以為我知道怎麼解決使用者的需求,結果沒有思慮周全,導致我為了解決需求 A 而做出了功能 A,反而冒出了痛點 B, C, D 等著我再次解決。 或者是使用者提出了一個需求,但其實這個需求是「他自己想好的其中一個解法」,有時候我們不見得要照做,我們可以在了解使用者背後真實的需求後幫忙思考是否有更好的解法。 以下我要來分享我實際遇過的兩個情況。 解法不只有一個 通常我們要解決一個需求可能會有非常多種方法,這時就會面臨到要如何做選擇。 舉一個實際的例子,在學校的選課系統中,選擇「開課系所」的選單非常長,因為包含了 168 個系所,每次我都要來回滾動好幾次才可以定位到我要找的系所。 在這裏我們要解決的需求是:幫助使用者快速的選到他要的目標。 根據這個目標,我可能就有三種方法去做: 若先不討論工程師實作的難易度,你會怎麼選擇呢?這三種解法分別有什麼優劣呢? 這個問題沒有絕對的答案,或者說在不同的情境下會有不同的答案。 在這裡我會選擇 A+C,我看到 Plan A 的缺點是必須要做輸入,會用到鍵盤,但因為我們可以預測使用這個選單的人應該是學生,對於用鍵盤打字不會太陌生,假如今天的情境,這個選單是給不熟悉鍵盤打字的族群使用,我可能就不會選擇 A。 另外,第一次面對這個問題的我以為最佳解是 Plan B,後來發現如果使用者不知道他想找的系屬於哪一個學院,那就糗大了。 在一些比較完整的產品團隊,大多會有專門的設計師在研究使用者,他們在設計前會做訪談、問卷調查以了解使用者的面貌,從客群的特性去找出較適合的方案,在產品上線之後一樣可以做調查、易用性測試,或做 A/B Testing 去比較不同的設計帶來的效益。...

May 29, 2021

使用 d3-brush 後文字不見?了解 svg 的顏色設定

前陣子,在修資料視覺化的同學寫作業遇到了一個問題,幫他解決後發現裡面有不少東西可以記錄下來。 這一篇會分成三個部分 解決同學遇到的 bug:使用 d3-brush 後文字消失 了解 d3-brush 的行為 d3-axis 顏色的有趣發現 使用 d3-brush 後文字消失 我們要看的是下面這段程式,也可以到我的 observable 看 render 的結果。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Demo</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-brush/1.0.4/d3-brush.min.js"></script> </head> <body> <svg width="100" height="100"></svg> <script> const brush = d3....

May 16, 2021