--- title: 'Flutter StatelessWidget vs StatefulWidget' tags: Flutter disqus: hackmd --- # Flutter StatelessWidget vs StatefulWidget **目錄:** [TOC] ## Widget 簡介 - 在Flutter中,一切皆是Widget(組件),Widget的功能是“描述一個UI元素的配置數據”,它就是說,Widget其實並不是表示最終繪製在設備屏幕上的顯示元素,而它只是描述顯示元素的一個配置數據。 - 實際上,Flutter中真正代表屏幕上顯示元素的類是Element,也就是說Widget 只是描述Element 的配置數據。並且一個Widget 可以對應多個Element,因為同一個Widget 對象可以被添加到UI樹的不同部分,而真正渲染時,UI樹的每一個Element 節點都會對應一個Widget 對象。 ## StatelessWidget - StatelessWidget相對比較簡單,它繼承自Widget類,重寫了createElement()方法。 - StatelessElement 間接繼承自Element類,與StatelessWidget相對應(作為其配置數據)。 - StatelessWidget用於不需要維護狀態的場景,並且只會被渲染一次,它通常在build方法中通過嵌套其它Widget來構建UI,在構建過程中會遞歸的構建其嵌套的Widget。 ## StatefulWidget - 和StatelessWidget一樣,StatefulWidget也是繼承自Widget類,並重寫了createElement()方法,不同的是返回的Element 對象並不相同;另外StatefulWidget類中添加了一個新的接口createState()。 - StatefulElement 間接繼承自Element類,與StatefulWidget相對應(作為其配置數據)。StatefulElement中可能會多次調用createState()來創建狀態(State)對象。 - createState() 用於創建和StatefulWidget相關的狀態,它在StatefulWidget的生命週期中可能會被多次調用。例如,當一個StatefulWidget同時插入到widget樹的多個位置時,Flutter framework就會調用該方法為每一個位置生成一個獨立的State實例,其實,本質上就是一個StatefulElement對應一個State實例。 ## Stateful與Stateless注意事項 - 盡可能用Stateless。 - Stateful Wigets盡量在越低層級的節點使用,避免過多不必要的重build。 - setState會觸發State.build,如果你的觸發是在根節點,會造成所有Widgets被重build,會是個效能問題。 - 詳細請看下篇([State狀態管理](https://hackmd.io/xKYGrc_8Tbm-ncdbz7qqaw)) ## 生命週期 1. initState(): 在 Widget 創建時調用,通常用於初始化操作,例如設置初始狀態或資源的鏈接。 2. didChangeDependencies(): 當 Widget 的相依項目發生變化時調用。這可能發生在初始化期間或 build 階段之後。 3. build(): 在 Widget 需要重新構建時調用。這是呈現實際 UI 的地方。build 方法在初始化和每次 setState 被調用時都會執行。 4. didUpdateWidget(): 在 Widget 被替換時調用。例如,父組件重建並傳遞新的 Widget 時。 5. deactivate(): 在 Widget 從樹中移除時調用。通常是在 dispose 之前。 6. dispose(): 在 Widget 被銷毀時調用。通常用於釋放資源,取消訂閱等清理操作。 >當你使用 setState 或外部事件觸發時,Flutter 會調用 build 方法來重新構建 UI。 > >同時,當 Widget 從樹中移除時(例如導航到其他頁面),相應的生命週期方法會被調用,以確保釋放資源並進行清理。 :::danger 請注意,StatelessWidget 沒有類似 initState、dispose 等方法,因為它們在構建之後不會被更新或銷毀。每次 build 調用時都會重新構建整個 StatelessWidget。 :::