源起為想要寫一個客制化的下拉選單,因為客制化程度很高,所以不適合使用原生的 <select> ,想說自己來刻一個 <DropDownList>

如果使用原生的 <select> ,若畫面上有2個以上的選單,第一個打開時,直接點選另一個 <select> ,則原本打開的會關閉,而剛選到的會打開。這是因為 <select><input> 這類的元素預設都有 focusblur 的事件屬性。但如果是使用 <div> 這種元素就沒辦法達到 focus/blur 的效果。

腦筋就動到如何利用 click事件,達到點選 <DropDownList> 內部時打開選單,而點選外部關閉。點選內部很容易,但外部的任意元素,就綁 click事件到document 身上。技巧在於

(1) 利用 click 事件的 event.target 回傳的Type 是 Node

(2) Node具有 contains 方法,可以判斷其是否包含另一結定的 Node

實作的範例如下,類似的情境應該也適用 Popup 和 Modal 類的 Component

筆記一下常用的 Git-Flow 指令集,需要時就無腦照抄

masterdevelop 為長期存在的 Long-running branches,其餘均為階段性任務 …

前幾天想要準備 vue 的測試環境,想說就是裝個 vue/test-utils 套件,結果弄了一個晚上,搞死自己。因為 Vue Test Utils 只是 mount Vue Componentd library,測試環境還是要自行準備。不但文件說不清楚, vue2 和 vue3還有點不同,決定要寫筆記,避免下次安裝環境又再搞到自己快瘋掉。

以下都 …

最基本的 axios 用法,設定一個baseURL

就可以輕易用 api.getData() 呼叫 api

現在針對錯誤訊息再多一點點改善

微調了一下,讓 api 有2個方法可以操作,其中 api.details() 如果放了錯誤的參數,就會跳到 error 並有 對應的 handler接它。而因為 error handler 應該要共用,所以寫在 axios.interceptors.response.use() 裡.

接著是抽離 requestresponse 讓 api 有更多的彈性和擴充空間,例如有更多組 api 的時侯,就可以更方的分類。

並且也使用 axios.interceptors.request.use 在每支api 發送request之前帶入 token

例如以上的程式,就可用
api.todos.create({ title: 'test' })
api.users.list()

最後就是改寫成 TypeScript啦

假設已經有一個docker image 叫 jaysonchiang/posts:0.0.1

Pod 起手式,建立一個 post.yaml

Observer Pattern 目的是讓多個物件(稱之為觀察者,Observer)可以接收單一來源(稱之主題,Subject)的訊息(Message)。每次派送(Publish)的訊息觀察者要不要使用,Subject一點也不在意;Subject只負責把Message送給所有訂閱(Subscribe)的Observer。

這種訂閱與派送的模式,也有人稱之為Pub/Sub。也有人說它們不一樣,就我來看機制是一樣的,而且設計的目的都是讓兩個實體解耦,只是實作上不同的而已。

我們要設計兩個物件,一個可被訂閱的 Observer;另一個是可以註冊這些 Observer 的發行者(Publisher),習慣上將這物件稱之為 Subject (主題)。

開發這個模式前,先定義好要可以讓 Subject 執行的 method 名稱,然後 Observer 會實作這個 method ,命名上用 update(message) 較好理解。所以 Observer 會長得像這樣:

上面的例子,joe 和 jayson都是 Observer ,可以各自實作當 Subject 執行 update 的時侯,收到的 message 要做什麼。

所以 Subject 至少有2個方法要實作,一是用來註冊Observer 的 subscribe(observer) ,二是派送訊息的 notify(message) ;並且有1個屬性 observers 用來儲存已經註冊的Observer 。

這樣就是最簡單的 Observer Pattern 了,執行起來會像這樣

每個 Observer 和 Publisher 之間唯一相依的部分就是一開始要定義的 update(message)

如果不在開發期間定義 update(message) ,而是Observer連同 method 一起註冊,Publisher 執行notify 的時侯,就不用在意 method的名稱,盡管把想要發布的資訊,更降低了彼些的耦和:

React- Redux 7.1 之後提供了 useSelector 的hook ,就不需要再使用 connectmapStateToProps

但是如果直接使用在 TypeScript 的時侯,因為 useSelector 並不知道 reducer 的型別,所以會有錯誤提示 :

我們需要手動在 reducer 增加型別給 useSelector 使用

並且另外自訂 useSelector hook,這樣每次使用原本 React-Redux 提供的 useSelector 才不會太冗長。

設計一個簡單的 Action Creator

使用 react-redux 的 hook useDispatch

上面的例子中,如果每次執行 dispatch 都要放入名稱很長的 actionCreators 會顯得很冗。所以把 dispatchactionCreators 一起抽離寫成 useActions

想像一個開發一個 Todo List ,使用 JavaScript 為 Add Todo 寫的 Redux Reducer :

改寫成 TypeScript 版本,先將 Action Type 改寫為 enum,再分為 stateaction 寫 interface。Action 的 payload 會因為 Action Type 的情境而不同,所以先暫時寫 payload?: any

現在專心討論 interface Action 的 payload:

(1) 在 ADD_TODO 的時侯是 沒有payload 。

(2) 當 ADD_TODO_SUCCESS 的時侯是Todo的陣列,所以是 string[]

(3) 當ADD_TODO_ERROR 的時侯是錯誤訊息,所以是 string

分別為這三種情況寫成3個 interface,即可避免使用 any

Jayson Chiang

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store