此次本文旨在討論:vue
首先,咱們先闡述下 react 組件更新的策略:一個組件發生了更新,其子組件也會更新,在不進行優化的狀況下,這種更新的傳遞會持續到組件樹的葉子組件,即便某個子組件先後props並無發生改變。react
而後,讓咱們肯定下什麼能夠引發組件更新(針對react 16):api
因爲 useReducer 的 api 過於繁瑣,爲了敘述的方便,這裏使用 useState 舉例子。數組
這一節中,我使用 setState 指代 useState hook 返回的 setState 函數,而 this.setState 指代類組件的 setState 函數。promise
關於 useState hook 須要注意的幾點:異步
hooks 給了函數組件和類組件同樣保存狀態的能力,天然而然的,既然能夠保存狀態就應該能夠更改狀態,useState 返回的 setState 能夠用於改變相關的狀態,自此函數組件和類組件同樣,一樣具備了主動發起更新的能力。函數
react 官方認爲 useState hook 應該用於更加細粒度的值,因此 useState 和基本的值類型數據配合良好,可是若是牽扯 object 類型,就須要做出一些額外的考慮:優化
setState 和 this.setState 阻止更新的行爲不同。不一樣於 this.setState(null),setState(null) 依舊會觸發更新,而且會把 state 賦值成 null。當你使用 setState 時,react 會將先後的 state 進行 === 比較,若是同樣,則不會觸發更新。因此若是你使用 useState 保存 object,即便新的 object 中的值沒有發生變化,可是因爲生成了新的引用,依舊會觸發更新。這也是爲何儘可能不要使用 useState 來儲存 object,對於複雜的本地狀態,建議使用 useReducer 來管理。this
關於 this.setState 須要的注意的是:spa
設置空對象 this.setState({}) 依舊會觸發更新
this.setState(null) 不會觸發更新
this.setState 同步異步問題:
在事件處理函數,或生命週期函數,react 會對 this.setState 做 batching 優化,此時 this.setState 是異步的。
其餘時候,例如 setTimeout 或 promise 中,this.setState 是同步的。
這是我想咬文嚼字的一節,在閱讀 react 相關文章時,常常會看到 props變化,致使組件發生了更新,這聽起來似乎 react 在更新時會對比先後的 props,只有發生了變化時纔會更新組件。又或者有過 vue 經驗的新人,可能認爲 react 對 props 對象進行了監聽,因此發生變化時纔會更新,然而,以上兩種解釋都是錯誤的。
function Box(props) {
const { count } = props;
return <div>{count}</div>;
}
function Counter() {
const [count, setCount] = useState(0);
const [useLessCount, setUseLessCount] = useState(0);
return (
<div> <Box count={count} /> <button onClick={() => setCount(prev => prev + 1)}>INC</button> <button onClick={() => setUseLessCount(prev => prev + 1)}>useLess</button> </div> ); } 複製代碼
當 INC 按鈕被點擊時,Box 組件顯示的數值加了 1,讓咱們走一遍這個 更新 的流程,看看 props 變化是否致使了組件 更新
流程:
縱觀整個流程,react 一直遵循着一個簡單的策略 組件更新,則更新其全部的子組件,且不斷遞歸的運用這個策略,直到葉子節點。和 props 自己沒有任何關係。也就是說,子組件的更新是因爲父組件更新引發的,而非 props 的變化
另外一個更直接的證據是,點擊 useLess 按鈕,一樣會致使 Box 組件更新,即便 count 的值並無發生改變。
props 變化,致使組件發生了更新,犯了一個典型的因果謬誤,A 先發生,而後 B 發生了,因此 A 致使了 B 發生。
這句話的主要問題在於,它會給初學者創建一種錯誤的心智模型,認爲其中有什麼 fancy 的 magic 發生,然而本質上只是遵循一個簡單更新策略的天然而然的結果。
最後,任什麼時候候,props 變化,致使組件發生了更新 這句話都是錯誤的,可是對於本小節中的例子來講:props 變化,致使組件內容發生了變化 是正確的。
既然都談了這麼多,我就多說一點,人在交流時,假若不對一些模棱兩可的詞語的意思做出規定,很是容易變成你們自說自話,我不一樣意你的,你不一樣意個人,誰也說服了不了誰。我本覺得這是技術討論的常識,然而卻發現知乎上天天都在發生這樣的對話,不多發現充滿價值的討論。