StatelessWidget
无状态组件无法改变,意味着外部传入的所有值都必须是固定的无法改变,因为StatelessWidget只会被渲染一次,对于StatelessWidget来说,整个生命周期只有build这个过程,整个组件的构建方法只会在三种情况下被使用(1)组件第一次被插入树中(2)组件的父组件状态改变(3)它所依赖的InheritedWidget发生变化
StatefulWidget
有状态组件持有的状态会在Widget生命周期中发生变化,会根据数据的变化进行多次渲染,因此StatefulWidget的生命周期会比StatelessWidget复杂。 一个StatefulWidget被实现至少需要两个类
- StatefulWidget类。
- State类,StatefulWidget类本身不可变,但是State类在Widget生命周期中始终存在,StateFulWidget将其可变状态存储在由createState 方法创建的State对象中,或者存储在State订阅的对象中。
StatefulWidget生命周期
- creatState: 该函数为StatefulWidget中创建State的方法,在StatefulWidget被创建时最先被调用的,一旦creatState被创建完成就代表当前组件已经在Widget树中,mounted被设为true,关于mounted的解释会在下面被提到。
- initState:在初始化State时会被调用,且只会被调用一次,因此,通常在其中放置一些一次性的操作,例如初始化数据,从后端获取数据来设置State
- didChangeDependencies:该函数是在该组件依赖的 State 发生变化时会被调用。这里说的 State 为全局 State,例如系统语言 Locale 或者应用主题等,Flutter 框架会通知 widget 调用此回调。类似于前端 Redux 存储的 State。该方法调用后,组件的状态变为 dirty,立即调用 build 方法。
- build:返回渲染的Widget,有可能会被多次调用。
- dispose:永久移除组件,并释放组件资源。调用完毕后,mounted被设为false,代表组件的生命周期结束。
相关概念
- mounted:State中的一个重要属性,用来表述组件是否在树中被加载,当调用creatState后,会被设为true,代表组件已被加载,当调用dispose后,mounted被设为false,代表当前组件已经被移除。
- dirty:表示当前组件为脏组件,之后会执行build重新渲染组件。
- clean:与dirty相对,表示不需要build
Flutter生命周期流程
- 初始化组件:主要是creatState和initState。
- 组件创建:didChangeDependencies和build。
- 对组件进行重建:因为didChangeDependencies、setState或者didUpdateWidget导致的组件重构,需要注意的是,这会导致整个组件被进行重构,如果只是有组件中一小部分的变动而导致整个组件进行更新会导致一些额外的开销,尤其是频繁重构的情况下,Flutter官方也不推荐大量使用这种方式,因此后续的优化重点主要就是在这个方面。
- 组件的销毁:dispose。
触发组件再次build
触发组件再build主要依赖三种方式:setState
、didChangeDependencies
、didUpdateWidget
。
- setState:这个比较好理解,重新设置组件状态之后自然就会触发整个组件的重构
- didChangeDependencies:组件依赖的全局state发生了变化时,也会调用build。
- didUpdateWidget:可以说明父组件的 State 变化会引起子组件的 didUpdateWidget 和 build,子组件自己的状态变化不会引起父组件的状态改变。同时父组件的移除也是自底向上的,显示移除子组件最后才是移除父组件。