提升 State
兩個元件要顯示或改同一份資料時,不要各放一份 useState。把它放到最近的共同父元件,再當 props 傳下去。官方稱為 lifting state up。
為什麼要往上提
假設 SearchBox 與 ResultList 都需要關鍵字:
function SearchPage() {
const [query, setQuery] = useState("");
return (
<>
<SearchBox query={query} onQueryChange={setQuery} />
<ResultList query={query} />
</>
);
}
- 輸入時
SearchBox呼叫onQueryChange,父元件更新query。 ResultList收到新的query,自動重畫。- 單一真相來源(single source of truth),不會出現兩邊關鍵字不一致。
判斷 state 該放哪
問:哪些元件需要讀它?哪些需要改它?
- 只有一個元件用:放在那一個裡。
- 兩個以上要用:放到它們的共同父元件。
- 隔很多層都在傳同一組 props:之後才考慮 Context,初學先把提升做好,避免過早抽象。
範例:選中的項目
function Gallery({ photos }) {
const [activeId, setActiveId] = useState(photos[0].id);
const active = photos.find((photo) => photo.id === activeId);
return (
<div className="gallery">
<img src={active.src} alt={active.title} />
<ThumbnailList
photos={photos}
activeId={activeId}
onSelect={setActiveId}
/>
</div>
);
}
縮圖列不自己記住「誰被選」,只負責顯示與回報點擊。大圖與縮圖永遠對得上。
官方對照:Sharing State Between Components。需要在載入後向伺服器要 photos 時,見 useEffect。