你有沒有遇過這種情況:
在 React 中渲染一個待辦清單,點了「新增任務」按鈕,結果輸入框的值跑到另一個項目去了?
這其實就是因為 少了正確的 key
。
在 React 裡,key
是一個特殊的 prop,用來幫助 React 辨識清單中的每個元素。
React 在更新 Virtual DOM 時,會根據 key
來比對新舊元素:
function TodoList({ todos }) {
return (
<ul>
{todos.map((todo, index) => (
<li key={index}>{todo.text}</li>
))}
</ul>
);
}
如果在最前面插入一個新任務,所有元素的 index 都會往後移。
因為 key = index,React 認為 key=0,1,2...
這些元素「還是同個」,於是會 錯誤地重用舊的 DOM 節點,只是把文字等 props 更新掉。
結果:文字顯示會正確,但像輸入框值、checkbox 勾選、focus 等 DOM 內部狀態或 component state 會跟錯項目 → UI 出現錯亂。
function TodoList({ todos }) {
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
}
這樣 React 就能準確知道:
「反正用 index 當 key 就好」
錯!當 list 會增刪或重排時,index 不穩定 → React 誤判 → UI 狀態錯亂。
「不用 key 也可以跑啊」
React 會自動 fallback 用 index,但你可能會遇到隱藏 bug,尤其是有輸入框、動畫或元件內部狀態時。
以下這段程式碼會有什麼問題?該怎麼修正?
<ul>
{['A', 'B', 'C'].map((item, index) => (
<li key={index}>
<input defaultValue={item} />
</li>
))}
</ul>
The
key
prop gives each item in a list a stable identity.
React uses keys to match old and new elements during reconciliation.
Without keys, React may reuse or rebuild the wrong DOM nodes, which can cause performance issues or even UI bugs, like input values jumping to the wrong item.
That’s why we should always use a unique and stable key, like an id, instead of the array index.
key
就像 list item 的身份證。
React 在比對新舊 Virtual DOM 時,會靠key
來判斷元素是不是同一個。
如果沒有 key,React 可能會重建錯誤的 DOM,導致效能變差,甚至出現像是輸入框值跑掉的 bug。
所以正確做法是用 唯一且穩定的 id 當 key,而不是用 array 的 index。
key
是 React 用來識別 list item 的身份證。key
→ React 能重用元素,只更新必要部分。id
當 key。