The Mystery of React Children Re-rendering
Component renderingက App တစ်ခုလုံးရဲ့ performanceအတွက် အရေးကြီးပါတယ်။ ဆိုတော့ ရိုး”လေးထင်ရပေမဲ့ ရှုပ်ထွေးတဲ့ children re render logic ကို shareပေးချင်ပါတယ်။
Basic အနေနဲ့
1. Component တစ်ခုမှာ setState ခေါ်ရင် အဲ့ component ကို re-render ဖြစ်စေပါတယ်။
2. Componentရဲ့ parent element အပြင် သူ့ရဲ့ သက်ဆိုင်ရာ component treeမှာရှိတဲ့ child elementတွေပါ re-render ဖြစ်စေပါတယ်။
ဆိုတော့ ဒီ blogမှာ မလိုအပ်ပဲ child component (Element) ကို re-render မဖြစ်ဖို့ children ချင်း တူပေမဲ့ ဘာကြောင့် re-render ဖြစ်လဲဆိုတာ ဘယ်လိုလုပ်ရင် မဖြစ်ဘူးလဲဆိုတာ ရှင်းပြသွားပါမယ်။
Example 1 — ပုံပါအတိုင်း Div elementမှာ mouse move event listenerတစ်ခုရှိတယ်။ handlerထဲမှာ setStateကို ခေါ်ထားတယ်။ဒါ့ကြောင့် mouse ရွေ့တိုင်းမှာ Child Componentအပါအ၀င် componentတစ်ခုလုံး re renderလုပ်ပါတယ်။
သုံးထားတဲ့ Child component က သာမန် featureလောက်ဆို ကိစ္စမရှိပေမဲ့ heavy ဖြစ်တဲ့ featureဆို performanceပိုင်းမှာ ပြဿနာရှိလာနိုင်ပါတယ်။
Example 2 — Child ကို direct ထည့်သုံးမဲ့အစား component prop children အနေနဲ့ သုံးမယ်ဆိုရင် Mouse eventကြောင့် moving componentက re render လုပ်တဲ့အခါ children က ထပ်ပြီး re render လုပ်မှာ မဟုတ်ပါဘူး။
childrenချင်းတူပေမဲ့ ဘာကြောင့် Re render မလုပ်လဲဆိုတာ သိဖို့ Reactရဲ့ behind the senses React.createElement နဲ့ reconciliation algorithm အကြောင်းကို အကြမ်းဖျင်းသိဖို့လိုပါမယ်။
React.create Element
- React Component တစ်ခုက React.createElement function ကနေ return ပြန်လာတဲ့ UI denifition object တစ်ခုဖြစ်တယ်။
- ဆိုတော့ Component re render လုပ်တဲ့အခါတိုင်း သူ့ထဲမှာ ရှိတဲ့ child componentတွေ အကုန်လုံးက သက်ဆိုင်ရာ React.createElement functionကို နောက်တစ်ခေါက် ထပ်ခေါ်ပါတယ်။
- ဘာကြောင့် createElement function ကို နောက်တစ်ခေါက်ထပ်ခေါ်ဖို့ လိုလဲဆိုရင် UI object defက immutable objectဖြစ်တယ်။
- ဒါကြောင့် UI update ဖြစ်စေချင်လို့ setStateခေါ်ပြီး re renderလုပ်ချင်တဲ့ အခါတိုင်း Componentထဲက createElement functionတွေက နောက်တစ်ခေါက်ထပ်runမှာပါ။
Reconciliation Algorithm
- အကြမ်းဖျင်းပြောရရင် re renderလုပ်ပြီးတဲ့ Virtual DOMနဲ့ မလုပ်ခင် Virtual DOM နှစ်ခု compareလုပ်တယ်။ ရလာတဲ့ resultကို ကြည့်ပြီး Update လုပ်ဖို့လိုတဲ့ componentတွေကို Actual DOMမှာ direct ပြင်တယ်။
ဘယ်လို Compareလုပ်လဲ / Component re renderလုပ်တာနဲ့ ဘာဆိုင်လဲဆိုရင်
- Compareတဲ့အခါ Component နှစ်ခုရဲ့ UI Def Objectက တူနေရင် အဲ့ componentကို re render ထပ်မလုပ်စေပါ။
- UI Def Object မတူဘူးဆိုရင် အဲ့ componentရဲ့ typeနဲ့ propsကို ကြည့်ပါတယ်။ တူနေတယ်ဆိုရင် re render လုပ်စေပါတယ်။ မတူဘူးဆိုရင် componentကို mountပြန်လုပ်ပါတယ်။
- Typeနဲ့ Propက ဘယ်လိုလဲဆိုရင် <div name=”hello world”/> ဒီနေရာမှာ typeက div မှာ propsက တော့ name=”hello world” ပါ။
Example 1 မှာဆိုရင်
- mouse eventကြောင့် component re render လုပ်တယ်။ re render လုပ်တဲ့အတွက် child componentတွေပါ React.createElement ထပ်runတယ်။
- ဆိုတော့ UI def objectက အသစ်ပြန်ဖြစ်တယ်။
- အကုန်နောက်တစ်ခေါက်ထပ်runပြီးတော့ Virtual DOM အသစ်ကိုရတယ် (UIမှာ updateမဖြစ်သေးပါဘူး) ။
- အဲ့နေရာမှာ reconciliation အလုပ်”တယ်။ re renderမလုပ်ခင် child componentနဲ့ လုပ်ပြီးတဲ့ child component တွေကို compareတော့ def object က မတူတော့ child componentကို re-render ဖြစ်စေပါတယ်။
Example 2 ( ဘာကြောင့် re render မဖြစ်လဲ )
- Child Componentက component prop children အနေနဲ့ ပို့တယ်။
- Child Componentက SomeOutsideComponent ထဲမှာ သုံးထားတယ်။
- Mouse eventကြောင့် Moving Component re renderဖြစ်ပေမဲ့ SomeOutsideComponentက re render မဖြစ်တဲ့ အတွက် propဖြစ်တဲ့ child componentရဲ့ def objectက အရင်ကနဲ့ တူတူပဲ။
- Reconciliation အဆင့် compareတဲ့အခါ re render မလုပ်ခင်နဲ့ လုပ်ပြီးတဲ့ componentနှစ်ခုဟာ တူတူပဲဖြစ်တဲ့အတွက် child componentကို re render မလုပ်တော့ပါဘူး။ Moving componentကတော့ re renderလုပ်ပါတယ်။
ဆိုတော့ နားလည်ကြမယ်ထင်ပါတယ်ခင်ဗျာ။