設計 UI 互動的時候,會思考當使用者進行各項操作的時候, UI 該怎麼改變:
必須考慮多種情境,透過 UI 的變化來反映多種狀況
利用 state 反應各種 input 的變法,作法大致如下:
定義元件各種不同的 UI 狀態?
例如,使用者填寫表單一連串的過程中,UI 元件的狀態:
什麽情況會觸發這些改變?
可以透過兩類 input 事件觸發狀態的改變
當這些 input 發生時,改變 state 變數
用 useState
來呈現這些的 UI 狀態?
當使用 useState
來代表不同 UI 狀態時,保持越簡單越好,每一組 state 變數都是可以改變的,組數越多越複雜也越難維護。
移除不必要的狀態變數?
在使用 state 變數時,有幾點可以注意:
isTyping
、isSubmitting
,但這兩個值不會同時為 true怎麼選擇適合的 state 資料結構 ?
將相關的 state 集合起來
如果多個 state 變數會同時改變,可以合併成同一個 state 變數
const [x, setX] = useState(0);
const [y, setY] = useState(0);
// 可以改寫成
const [position, setPosition] = useState({ x: 0, y: 0 });
避免 state 之間的矛盾
例如 isSending
、isSent
絕對不會同時為 true,可用 status
來儲存三種狀態,typing、sending、sent
const [isSending, setIsSending] = useState(false);
const [isSent, setIsSent] = useState(false);
// 可以改寫成
const [status, setStatus] = useState('typing');
避免多餘的 state
假設在執行過程中,已經從元件的 props 或是從 state 變數計算得到某些資訊,就不用再把這樣的結果存進 state 變數中
// fullName 是從 firstName 和 lastName 得到的
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [fullName, setFullName] = useState('');
// 可以改寫成
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const fullName = firstName + ' ' + lastName;
避免 state 變數資料的重複
同一份資料在不同的 state 變數中,很難保持資料一致,避免複製資料內容
// selectedItem 和 items 中項目內容是一樣的
const [items, setItems] = useState(initialItems);
const [selectedItem, setSelectedItem] = useState(
items[0]
);
// 可以改寫成
const [items, setItems] = useState(initialItems);
const [selectedId, setSelectedId] = useState(0);
避免巢狀結構太深的 state 變數
太多層的結構,會越難更新資料
如果要在多個元件之間共享 state,可將 state 移至最接近的父元件中,透過 prop 傳遞給子元件,將控制權交給外部父元件,保持每個狀態的 single source of truth。
React 也是利用樹狀結構來建置管理 UI,透過 JSX
建立 UI tree
,接著 React DOM
再去更新對應位置的 DOM 元素
。
state 實際上是 React 透過其元件在 UI tree 中的位置而定,而不是真的儲存在元件內部,所以 state 認的是位置而不是所屬元件。
這兩個 counter 是因為在 tree 中的位置不同,所以被視為兩個不同的獨立元件
export default function App() {
const counter = <Counter />;
return (
<div>
{counter}
{counter}
</div>
);
}
同一個元件在同一個 UI treee 位置,React 就會保留元件,也包含其狀態,如果是不同的元件,在同一個位置,state 則會被重新設定。
如果希望每次 re-render 時,state 可以保留,要記得每一次的 render UI tree 的結構要一致。如果結構不同,React 會從 tree 中移除元件,也一併移除 state。
如果"視覺上"元件要在同一個位置,卻又想要重設 state,可透過以下兩種方式: