今天我們接續前一篇的案例,再來講講一些NG的案例,總是會有一些講不聽不想拆 component 的人,在新版本的環境下應該會被強制修改,因為如果不改的話會被重置 state,我們看個簡單的範例:
import React, { useState } from "react";
export default function App() {
const [count, setCount] = useState(0);
const onAdd = () => setCount(count + 1);
const onMin = () => setCount(count - 1);
// 把他塞回來
const TxtInput = () => {
const [val, setVal] = useState("");
const txtChange = (e) => setVal(e.target.value);
return (
<>
<input value={val} onChange={txtChange} />
</>
);
};
return (
<div className="App">
<div style={{ display: "flex", justifyContent: "center" }}>
<button
onClick={onMin}
style={{ border: 0, borderRadius: "10px", margin: 4, width: 40 }}
>
-
</button>
<p>{count}</p>
<button
onClick={onAdd}
style={{ border: 0, borderRadius: "10px", margin: 4, width: 40 }}
>
+
</button>
</div>
<TxtInput />
</div>
);
}
然後你來到畫面操作,如下:
先在輸入框輸入字元
觸發任意上方按鈕
這是因為batch updating的問題所造成的,要解決這樣的問題只要簡單地將 TxtInput
移到外面就好了,如下:
import React, { useState } from "react";
// 把它拆出來,目的是不要讓他和其他的組件混到生命週期
const TxtInput = () => {
const [val, setVal] = useState("");
const txtChange = (e) => setVal(e.target.value);
return (
<>
<input value={val} onChange={txtChange} />
</>
);
};
export default function App() {
const [count, setCount] = useState(0);
const onAdd = () => setCount(count + 1);
const onMin = () => setCount(count - 1);
return (
<div className="App">
<div style={{ display: "flex", justifyContent: "center" }}>
<button
onClick={onMin}
style={{ border: 0, borderRadius: "10px", margin: 4, width: 40 }}
>
-
</button>
<p>{count}</p>
<button
onClick={onAdd}
style={{ border: 0, borderRadius: "10px", margin: 4, width: 40 }}
>
+
</button>
</div>
<TxtInput />
</div>
);
}
這就是為什麼不建議在 component 裡面塞 component 的原因,因為你沒有處理 memo
或是用 useCallback
去封包,那它就是會被當成是新的 refference 去處理。
那如果要在裡面處理的話就要加入 useEffect
去判斷,這裡正常人的選擇應該還是簡單拆分出去就好,所以要養成拆組件的習慣,然後要知道為何而拆可以參考我之前的文章。
希望這次的分享,能讓大家更認知到什麼是我們應該要盡量避免的作法,同時有解答到你們剛好發生錯誤的瞬間。
錯誤就是錯誤,不是 coding style 的問題,而是對 jsx 及其運行方式不熟悉,因為現在以 jsx 為基礎做開發的框架,早就不止 React 一家了,相同的問題也會發生其他 jsx 新興的框架當中。
我遇過很多新手會找藉口來合理化自己懶惰的行為,讓自己活在『自己以為』的認知裡面,錯誤發生就怪框架、怪工具設計不好,但往往就忽略了自己錯誤的觀念和使用習慣,這樣的狀態真的不好。
前端的問題不僅僅是靠框架,最重要的三元素仍然還是 Html/javascript/css,如同前面解釋過的底層概念一樣,整個 React 還是遵守 Javascript 本身的處理機制,當我們開發專案的時候也可以想一想:
如果把它當成是一般的 Javascript 我還會這樣處理嗎?還是會保持 Singleton pattern 的概念做整理呢?