React中不同的key产生的影响

回到文章
<div class="desc">
  <p>主要用来测试不同的key对节点diff的影响</p>
  <p>1. 选择不同的key的类型</p>
  <p>2. 可以任意点击“最前新增”或“后面新增”两个按钮,添加元素</p>
  <p>3. 在输入框中输入任意字符,目前输入框是非受控组件</p>
  <p>4. 再次任意两个按钮,观察效果</p>
</div>
<div id="root"></div>
#root, .desc {
  font-size: 16px;
  padding: 20px;
}
#root p,
#root div {
  padding: 6px 0;
}
#root input {
  margin: 0 6px;
}
const { useEffect, useState, useRef } = React;

function App() {
  const keyRef = useRef("uid");
  const [list, setList] = useState([{ id: 0 }]);

  const getItemKey = (item, index) => {
    switch (keyRef.current) {
      case "uid": {
        return item.id;
      }
      case "subIndex": {
        return index;
      }
      case "randomId": {
        return Math.random();
      }
      default: {
        return item.id;
      }
    }
  };

  // 修改key的类型
  const handleOnChangeKeyType = (event) => {
    keyRef.current = event.target.value;
    setList([{ id: 0 }]);
  };

  const handleAddClick = (type) => {
    setList((list) => {
      const item = { id: Date.now().toString(36) };

      if (type === "prev") {
        return [item].concat(list);
      }
      return list.concat(item);
    });
  };

  const handleDelClick = (id) => {
    setList((list) => list.filter((item) => item.id !== id));
  };

  return (
    <div className="App">
      <p>
        <span>请选择key的类型:</span>
        <select onChange={handleOnChangeKeyType}>
          <option value="uid">唯一id</option>
          <option value="subIndex">数组的下标</option>
          <option value="randomId">随机数</option>
        </select>
      </p>
      <p>
        <button onClick={() => handleAddClick("prev")}>最前新增</button> |{" "}
        <button onClick={() => handleAddClick("next")}>后面新增</button>
      </p>
      <div>
        {list.map((item, index) => {
          const key = getItemKey(item, index);

          return (
            <div className="item" key={key}>
              <span>key: {key}</span>
              <input />
              <a href="javascript:;" onClick={() => handleDelClick(item.id)}>delete</a>
            </div>
          );
        })}
      </div>
    </div>
  );
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);