0%

前言

最近安裝 highcharts 來試玩,因為之後公司的網頁有可能會換圖表套件,想要找一個比現在用的 lightweight chart 再更靈活一點的,畢竟他的主力是在 financial charts,拿來做股市圖蠻不錯的,但圖表類型很少連圓餅圖都沒有。

研究的過程中遇到一個 type error 覺得蠻有意思的。

想要從圖表提取 x, y 以外的資料

我想要做的功能是:當滑鼠指到圖上的任一點,圖表外的某處就要顯示該點的 x,y 值,以及另一個附加的資料。類似下面這樣(lightweight chart)

這張圖看起來不就是把 y 值提出來而已嗎?這樣有什麼困難?但其實我背後是把 y 值設為幣價的絕對值,以此來做圖。至於 y 軸會變成百分比是因為 lightweight chart 有提供一個功能讓我可以用百分比來顯示。

現在我要用 highcharts 做到一樣的事情,在設定 data property 時應用物件的方式定義 x,y 以及額外的資料,而不是用陣列的方式定義,請看以下

1
2
3
4
5
6
7
8
9
10

const options {
data: [[1,20,'extra1'], [2,23,'extra2'], [3,19,'extra3']], //不要這樣定義
data: [
{x: 1, y: 20, extra: 'extra1'},
{x: 2, y: 23, extra: 'extra2'},
{x: 3, y: 19, extra: 'extra3'}
] //應該這樣定義
}

這樣一來就可以用series.point.event.mouseover觸發 hover event ,再藉由 callback function 裡的this去取值,但這就遇到 Typescript 的問題了

如果 this 跟想像的不一樣怎麼辦

我想這是因為我定義了額外的屬性,雖然 highcharts 好心的幫我加進去 this,但是新的AUM屬性就是不存在在this的type(實際上是Highcharts.Point)裡面啊,但我要怎麼讓這個 type error 消失啊?

optional chaining 不行,this 也不能 assign 到別的變數(no-this-alias error)

研究好一段時間之後,這樣就可以了:

1
2
3
{
AUM: (this as typeof this & { AUM: string }).AUM
}

結論

一般來說遇到這種問題應該要去修改最根本的 type 定義,但今天遇到的是特殊狀況,我要怎麼從源頭修改 this 的 type 啊?
現在終於知道原來可以在 dot notation 前面用括號刮起來用as,又多知道一個應急的方法了

最近的一些小小心得

前幾天設計師同事說他從沒想過Figma讓design跟dev走得這麼近。

Figma相較於過去的UI設計工具,引入了很多工程思維,元件化、auto layout、variable這些概念可以讓排版、出畫面變得更快更一致也更好管理。

但我相信這些功能對沒有太多UI經驗的設計師來說除了不好理解以外也不知用意何在。幾個月前同事問我Figma Token的問題,我剛好有稍微研究過記得大概的用法,基本上就是json的運用,但對方還是容易不解為什麼要這樣做。設定了一大堆東西卻‘看似’只能用來切換深色模式,另外token的mapping(alias)、variants也是設計領域相對陌生的東西。

後來她離職了,公司剩另一位更不熟Figmaㄉ設計師。出圖永遠現場拉,連frame都常常沒包,沒元件化的結果導致UI總是不一致,畫面一改就全都得重拉。雖然有想排整齊卻很難做到,也缺乏對齊方式等RWD資訊。同時我們也欠缺一個有效管理Figma檔案的方式,我們永遠找不到最新的畫面,都是三百年前的頁面配新的UI,還常害校稿的同事改到舊的文案。

在獲得允許可以實驗性的大改Figma file後,我開始研究要怎麼妥善管理元件、頁面、spec,幫忙補 UI,教怎麼用 auto layout 處理 resizing。

也畫了架構圖向設計師說明元件庫、專案、畫面之間的關係,解釋為什麼這麼做能改善迭代的效率。但就像前面說的,工程思維滿類似寫程式時的 design pattern,對工程師來說相對熟悉,卻對設計師而言很陌生,問了不少次「為什麼要這麼麻煩」。但我不認為這是一個只適用於程式面的技巧,只要是需要迭代、管理、量產,就一定會受用。

當這些工程思維被建立起來後,除了能提升效率,也多了一些共通語言,不會一直有種設計跟工程兩個世界的感覺。我覺得前端(至少在我這)就是同時存在在這兩個世界的角色,沒有非常隸屬於任何一邊,但我感覺有一點點責任去把這兩個世界拉近一點。

前言

說到 React 的狀態管理工具
之前只有在線上課程學到 Redux
但由於之前的專案只需要用到 global state 而已
甚至不需要 useReducer 的功能
加上 Redux 在設定上還蠻複雜的
有 store, action, reducer, slice 等概念
讓我一直覺得大材小用的感覺
每次要用到新專案
基本上都要把 doc 從頭讀一遍XD

直到後來在公司接手外包前端的專案
發現他用了 Recoil 這個狀態管理工具
起初還有一點小排斥
但當我理解用法後
簡直開闢了新天地

Recoil

facebook 開發的 React 狀態管理工具
採用 atom 的架構,跟 Redux 的 flux 架構不同

相較於 Redux 輕量很多
很多時候我們只是想要單純使用 global state
而不打算用到 middleware 或是 reducer, actions 來管理狀態變化。
這時 Recoil 就非常方便。

初始化

要使用 Recoil 前置作業非常少
npm install recoil 安裝之後
用 RecoilRoot 包住整個 app
這樣就好ㄌ

1
2
3
4
5
6
7
import {RecoilRoot} from 'recoil'

...

<RecoilRoot>
<App/>
</RecoilRoot>

Atom

狀態的最小單位,初始化時需給予一個唯一的key以及初始值。
元件可利用 useRecoilStateuseRecoilValue 來 subscribe 任一 atom
當這個 atom 發生變化時
所有 subscribe 它的元件都會更新。

1
2
3
4
5
6
const nameState = atom({
key: 'nameState',
value: ''
})

const [name, setName] = useRecoilState(nameState)

Selector

一個 pure function
傳入值可以是 atom 或是別的 selector。

Selector 用來處理 derived data
根據 state 計算而得的值。讀值時使用 useRecoilValue

1
2
3
4
5
6
7
8
9
10
const fontSizeLabelState = selector({
key: 'fontSizeLabelState',
get: ({ get }) => {
const fontSize = get(fontSizeState);
const unit = 'px';
return `${fontSize}${unit}`;
},
});

const fontSizeLabel = useRecoilValue(fontSizeLabelState)

心得

Recoil 實在是很方便
包上 <RecoilRoot>,建立 atom,立刻就能用

官網:https://recoiljs.org