# 组件生命周期与Model状态控制 新接触FineUI的人很容易搞不清组件生命周期,写出不恰当的状态控制代码 ## 误区:在mounted的时候异步初始化数据 举一个常见的例子: 下面的书写形式,在组件mounted之后再去发送请求初始化状态,而后由watch调用组件的setSelected方法修改状态 这样有什么不好吗? 首先请求过慢的话会导致switch开关闪一下,其次mounted之后再修改组件会导致无谓的回流重绘 ```javascript class Model extends Model { state() { return { clusterOpen: false }; } actions = { initConfig: () => { // res return Promise.resolve(() => { this.model.clusterOpen = res.clusterOpen; }); } }; } class Widget extends BI.Widget { watch = { clusterOpen: b => this.switch.setSelected(b) }; mounted() { this.store.initConfig(); } render() { return { type: "bi.switch", selected: false }; } } ``` 恰当的方式是对需要初始化配置的场景采用异步组件形式,在`beforeRender`生命周期中做好状态获取,在组件被挂载到DOM上之前完成组件控制 这期间也可以根据需要做loading与loaded处理. ```javascript class Model extends Model { state() { return { clusterOpen: false }; } actions = { initConfig: () => { // res return Promise.resolve(() => { this.model.clusterOpen = res.clusterOpen; }); } }; } class Widget extends BI.Widget { beforeRender() { return this.store.initConfig(); } render() { return { type: "bi.switch", selected: this.model.clusterOpen }; } } ``` ## 在初始化state的时候可以直接根据options来 封装一个独立的组件的时候,组件内部用到了model,有时候需要把外部传来的props用做初始状态 ```javascript class Model extends Model { state() { const { clusterOpen } = this.options; return { clusterOpen: clusterOpen }; } } @store(Model, { props: () => { return { clusterOpen: this.options.clusterOpen }; } }) class Widget extends BI.Widget { render() { return { type: "bi.switch", selected: false }; } } ```