Skip to content

Instantly share code, notes, and snippets.

@YouMinTW
Created November 10, 2020 05:27
Show Gist options
  • Save YouMinTW/a6fd3c61d4a62fc1263876205389d869 to your computer and use it in GitHub Desktop.
Save YouMinTW/a6fd3c61d4a62fc1263876205389d869 to your computer and use it in GitHub Desktop.

目標

1. 用戶可修改文字框的值

2. 按下 Change Value 鈕也能改變文字框的值

題目

1. 請描述發生的問題?

Generate 按鈕 以及 text input 均無法正確顯示畫面


2. 發生問題的原因?

  1. <ContextInput> 取出 context 後便直接放入 useState 預設值。

  2. useState 預設值給定 context 之後, context 就算繼續更新,也不會重新預設 useState 的初始值

  3. 希望畫面顯示(更新)global state (context),卻只顯示 local state inputData 的畫面 <div>Context value: {inputData}</div>

  4. 底下 input 也只有更新 local state,並未更新 global state,因此 global state context 就算被按鈕改變,並不會影響,<ContextInput> 的畫面渲染

  5. 抓取元素的方式,也應該修正 e.valuee.target.value


3. 針對此問題的解法?

方法(1).移除 inputData ( local state )

直接將 <input> 的 value / onChange 與 context, setContext 掛鈎,

方法(2).若inputData有其他用途,需繼續保留

則必須透過 useEffect,同步雙向更新 context (global) 及 inputData (local)

useEffect(() => {
     setContext(inputData);
}, [inputData]);
useEffect(() => {
    setInputData(context);
}, [context]);

4. 是否有其它方式可從根本避免此問題發生?

避免 <ContextInput> 修改 local state 卻希望改變 global state,如此隱含地 implicit behavior,

Implicity 將造成極大的心理認知負擔認知轉換 ( context switch ) ,將造成未來除錯的困難

  1. 與設計師、PM討論該元件的行為及心理預期,重新釐清需求來修正程式碼。

  2. 避免透過 <input> 直接修改 global state

  3. 可改使用 <Form> 在 onsubmit 事件發生時,將 input value (local state),透過 handleSubmit 塞進 global context

  4. 若實際商業應用與實務需求為此,則傾向直接透過方法1在input上修改、明顯示出該 input 就是希望修改 global state


5. 有其它想法或觀察嗎?

1. 型別統一 (型別不一致,可能造成未來除錯困難)

Generate 按鈕 Math.random().toString() 希望顯示亂數型別為字串(String)

context 的預設值卻給定數字(Number) 0

另外<input type="text"> 的 value 只會產出 字串(String)未定義(undefined))

2. 考量到 performance,因為 input 直接修改了context, 可透過 throttle 或 debounce 節流。

如果有API call 可以另外再跟throttle 或 debounce 搭配來取消 request

3. input restriction / validation

如果需求上,我們的 input 只希望輸入數字,我們可以在 type 上,type="text"type="number",提前預防使用者輸入錯誤。

而在使用者輸入完成後,也可以搭配一些 validation 來驗證 input 是否合法、符合需求

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment