自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

關(guān)于 Flutter 中 Mounted 屬性您需要了解的一切

開發(fā) 前端
我在 StackOverflow 上看到很多關(guān)于無(wú)論如何都要在任何地方使用 mounted 屬性的必要性的問(wèn)題。請(qǐng)記住,使用 mounted 屬性不是強(qiáng)制性的,但這是一個(gè)很好的做法。在特殊情況下使用的良好實(shí)踐。

今天,我們來(lái)回顧一下 Flutter 中對(duì)于保證 widget 交互穩(wěn)定性起著重要作用的一個(gè)屬性。該屬性的名稱是 mounted。

什么是已 mounted 屬性?

Mounted 屬性是 Flutter 框架在 State 類中提供的布爾標(biāo)志。它指示狀態(tài)對(duì)象當(dāng)前是否在小部件樹中。

創(chuàng)建 State 對(duì)象之后、調(diào)用 initState 之前,框架通過(guò)將 State 對(duì)象與 BuildContext 關(guān)聯(lián)來(lái)“mounted”該對(duì)象。State 對(duì)象保持掛載狀態(tài),直到框架調(diào)用 dispose,之后框架將不再要求 State 對(duì)象再次構(gòu)建。換句話說(shuō),當(dāng)一個(gè) widget 從 widget 樹中刪除時(shí),其關(guān)聯(lián)的狀態(tài)對(duì)象也被刪除,并且 mounted 屬性被設(shè)置為 false。

mounted 屬性的目的是什么?

Mounted 屬性的主要目的是幫助您管理狀態(tài)并避免與不再屬于小部件樹一部分的小部件交互時(shí)可能發(fā)生的潛在錯(cuò)誤。具體來(lái)說(shuō),mounted 在涉及異步操作或延遲操作的場(chǎng)景中很有用。

何時(shí)使用 Mounted 屬性?

我認(rèn)為應(yīng)該把第一名讓給異步操作。

當(dāng)執(zhí)行異步操作(例如網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫(kù)查詢)時(shí),一旦操作完成,狀態(tài)對(duì)象可能會(huì)被更新。但是,如果在操作完成之前將小部件從小部件樹中刪除,則嘗試更新?tīng)顟B(tài)可能會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。在這種情況下,mounted 屬性允許您在進(jìn)行任何更新之前檢查狀態(tài)對(duì)象是否仍然處于活動(dòng)狀態(tài)。

String _data = '';
bool _isFetching = false;

@override
 void initState() {
   super.initState();
   _fetchData();
 }

void _fetchData() async {
  // assuming that _isFetching is a boolean that tracks the loading state
  setState(() {
    _isFetching = true;
  });

  try {
    final data = await fetchDataFromServer();
    if (mounted) {
      setState(() {
        _data = data;
        _isFetching = false;
      });
    }
  } catch (error) {
    if (mounted) {
      setState(() {
        _isFetching = false;
        _error = error;
      });
    }
  }
}

異步操作完成后,我們?cè)谡{(diào)用 setState 之前檢查 Mounted 屬性。這確保了小部件仍然是小部件樹的一部分。

為什么這很重要?同樣,如果小部件已從樹中刪除(例如,由于導(dǎo)航離開頁(yè)面或小部件被處置),調(diào)用 setState 將導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。在這里,我們的輔助 Mounted 屬性通過(guò)確認(rèn)小部件仍然處于活動(dòng)狀態(tài)并且可以安全更新來(lái)防止這種情況發(fā)生。

讓我們進(jìn)入下一個(gè)環(huán)節(jié):計(jì)時(shí)器和延遲操作、動(dòng)畫。

當(dāng)使用計(jì)時(shí)器、延遲操作或動(dòng)畫時(shí),小部件可能會(huì)在計(jì)時(shí)器或操作完成之前被丟棄。如果在調(diào)用 setState 之前檢查 mounted 屬性,就能確保只有在部件仍處于活動(dòng)狀態(tài)時(shí)才進(jìn)行更新。

void _startTimer() {
  Timer.periodic(Duration(seconds: 1), (timer) {
    if (mounted) {
      setState(() {
        _counter++;
      });
    }
  });
}

在 dispose 方法中,清理任何資源或取消正在進(jìn)行的操作至關(guān)重要。由于當(dāng)小部件即將從小部件樹中刪除時(shí)會(huì)調(diào)用 dispose,因此最好在執(zhí)行可能依賴于小部件狀態(tài)的操作之前檢查 mounted 屬性是一個(gè)很好的做法。

@override
void dispose() {
  _timer?.cancel();
  super.dispose();
}

另一個(gè)是:Navigator。

如果要執(zhí)行可能被導(dǎo)航中斷的異步操作(如使用 Navigator.push 或 Navigator.pop),請(qǐng)確保在更新?tīng)顟B(tài)前掛載部件。

Future<void> _navigateAndFetchData() async {
  Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => AnotherPage()),
  );

  final result = await someAsyncOperation();
  if (mounted) {
    setState(() {
      _data = result;
    });
  }
}

我想討論的最后一個(gè)是:具有異步初始化的有狀態(tài)小部件。

對(duì)于在 initState 中執(zhí)行異步操作的有狀態(tài)小部件,最好使用 Mounted 屬性來(lái)確保僅在小部件處于活動(dòng)狀態(tài)時(shí)才發(fā)生更新。

@override
void initState() {
  super.initState();
  _initializeAsync();
}

Future<void> _initializeAsync() async {
  final data = await fetchData();
  if (mounted) {
    setState(() {
      _data = data;
    });
  }
}

好吧好吧,這是最后一篇:長(zhǎng)時(shí)間運(yùn)行的操作。

對(duì)于長(zhǎng)時(shí)間運(yùn)行的任務(wù),例如文件 I/O 或計(jì)算,您可以在調(diào)用 setState 之前使用 Mounted 屬性來(lái)確保 UI 更新是安全的。

Future<void> performLongRunningTask() async {
  await longRunningTask();
  if (mounted) {
    setState(() {
      _taskCompleted = true;
    });
  }
}

為什么要使用 Mounted 屬性?

如果總結(jié)我們的討論,我們得到的是:

  • 防止運(yùn)行時(shí)錯(cuò)誤:在不檢查 mounted 的情況下,存在嘗試更新已刪除的小部件的風(fēng)險(xiǎn),從而導(dǎo)致運(yùn)行時(shí)異常。這在操作完成時(shí)間不可預(yù)測(cè)的異步操作中尤其常見(jiàn)。
  • 生命周期管理:mounted 屬性提供了一種管理 widget 生命周期的方法,確保只有在 widget 處于活動(dòng)狀態(tài)時(shí)才執(zhí)行操作。
  • 效率:通過(guò)避免對(duì)非活動(dòng)部件進(jìn)行不必要的更新,mounted 屬性有助于有效管理資源,從而提高應(yīng)用程序的性能。

什么時(shí)候 mounted 屬性可能不是必需的?

同步操作:用于不涉及異步任務(wù)或后臺(tái)操作的純同步操作。然而,確保適當(dāng)?shù)馁Y源管理并避免在小部件處置期間更新?tīng)顟B(tài)仍然很重要。

簡(jiǎn)單小部件:適用于不涉及任何異步邏輯、后臺(tái)任務(wù)或復(fù)雜生命周期管理的簡(jiǎn)單小部件。

在 Flutter 3.7 中使用 context.mounted

在 Flutter 3.7 之前,無(wú)法檢查 Flutter 中是否安裝了 StatelessWidget。這只能在 State/Stateful 小部件上實(shí)現(xiàn)。

但從Flutter 3.7開始,BuildContext 本身就有一個(gè) mounted 屬性。

這使得檢查是否安裝了任何小部件變得很容易,并且您可以從任何地方檢查它,無(wú)論它來(lái)自 StatefulWidget State 還是來(lái)自 Stateless widget,就像這樣:

// inside any widget
@override
Widget build(BuildContext context) {
  return ElevatedButton(
    child: const Text('Submit'),
    onPressed: () async {
      await doSomeAsyncWork(); // a method that returns a Future
      if (context.mounted) {
        Navigator.of(context).pop();
      }
    },
  );
}

我在 StackOverflow 上看到很多關(guān)于無(wú)論如何都要在任何地方使用 mounted 屬性的必要性的問(wèn)題。請(qǐng)記住,使用 mounted 屬性不是強(qiáng)制性的,但這是一個(gè)很好的做法。在特殊情況下使用的良好實(shí)踐。

原文:https://medium.com/@wartelski/everything-you-need-to-know-about-the-mounted-property-in-flutter-b603fdb51cb4

責(zé)任編輯:武曉燕 來(lái)源: 獨(dú)立開發(fā)者張張
相關(guān)推薦

2021-08-09 14:40:02

物聯(lián)網(wǎng)IOT智能家居

2023-03-29 21:05:03

布線結(jié)構(gòu)化布線

2024-04-10 11:47:34

2023-12-29 09:50:51

智能機(jī)器人人工智能

2022-03-14 16:50:54

物聯(lián)網(wǎng)IoT云計(jì)算

2023-06-25 10:14:46

智能機(jī)器人人工智能

2020-05-12 16:10:34

Wi-Fi網(wǎng)狀網(wǎng)絡(luò)網(wǎng)絡(luò)

2023-05-28 18:21:32

2023-08-11 08:00:00

人工智能Keras 3.0

2023-12-06 14:07:56

數(shù)字孿生AI

2021-12-29 14:24:12

物聯(lián)網(wǎng)IoT5G

2021-08-06 06:51:15

TypeScript Any 類型

2018-07-18 09:00:00

區(qū)塊鏈職位工作崗位

2018-09-27 18:56:25

區(qū)塊鏈

2024-01-09 15:04:29

Cat6a電纜以太網(wǎng)

2018-04-19 09:00:00

PythonAnacondaCPython

2022-12-01 10:08:43

預(yù)測(cè)性維護(hù)物聯(lián)網(wǎng)

2022-01-05 11:02:44

物聯(lián)網(wǎng)開發(fā)物聯(lián)網(wǎng)IOT

2020-05-12 10:43:24

物聯(lián)網(wǎng)數(shù)據(jù)技術(shù)

2023-04-12 14:04:48

光纖網(wǎng)絡(luò)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)