簡體   English   中英

有狀態與無狀態的區別如何影響何時重建小部件?

[英]How does the stateful vs. stateless distinction affect when widgets will be rebuilt?

我想了解狀態和提升狀態在 Flutter 中是如何工作的。 在下面的代碼中,我制作了一個簡單的應用程序,我試圖通過多個級別傳遞或提升一個字符串和一個函數。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String data = 'MyApp class data';

  void setTextField(String s) {
    setState(
      () {
        data = s;
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MainApp(data, setTextField),
    );
  }
}

class MainApp extends StatelessWidget {
  final String mainAppData;
  final Function setTextField;
  MainApp(this.mainAppData, this.setTextField);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(mainAppData)),
      body: Container(
        child: Level2(mainAppData, setTextField),
      ),
    );
  }
}

class Level2 extends StatelessWidget {
  final String level2Data;
  final Function setTextField;
  Level2(this.level2Data, this.setTextField);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Level3(level2Data, setTextField),
    );
  }
}

class Level3 extends StatefulWidget {
  final String level3Data;
  final Function setTextField;
  Level3(this.level3Data, this.setTextField);

  @override
  _Level3State createState() {
    print('Level3: $this.level3Data');
    return _Level3State(this.level3Data, this.setTextField);
  }
}

class _Level3State extends State<Level3> {
  String level3Data;
  Function setTextField;
  _Level3State(this.level3Data, this.setTextField);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        TextField(
          onChanged: setTextField,
        ),
        Text(level3Data),
      ],
    );
  }
}

當應用程序啟動時, _MyAppState狀態類中的字符串data會在構建MainApp時傳遞給MainApp StatelessWidget。 然后以類似的方式將信息傳遞給Level2 StatelessWidget 和Level3 StatefulWidget。

Level3中的TextField發生變化時,觸發setTextField setTextField是在MyApp中定義的,我認為當 String data發生變化時(在setState()內部)它應該觸發重建所有受變化影響的小部件。

MainApp小部件 (appBar) 中的文本發生變化,顯示MainApp已按預期重建。 但是Level3小部件沒有任何反應; 它沒有重建。 createState()方法中的 print 語句不執行,Text 小部件的文本不改變。

為什么Level3 StatefulWidget 不重建?

據我所知,有狀態的小部件 Level3 已經在樹中的給定位置創建。 並且根據有狀態小部件的契約,小部件實現者有責任確保在此類狀態更改時及時通知 State,使用 State.setState。 因此,在您的情況下,您需要在 level3 中設置 setstate 才能再次收到更改通知。 重建只發生在級別 1,因為調用了 setState。

重建過程遞歸地繼續,直到用戶界面的描述完全具體。 在級別 3 中,該類有自己的一組字段 String level3Data; 函數設置文本字段; 這意味着這些需要使用 SetState 再次設置,或者如果您執行類似的操作,則小部件構建將繼續。

class Level3 extends StatefulWidget {
  final String level3Data;
  final Function setTextField;
  Level3(this.level3Data, this.setTextField);

  @override
  _Level3State createState() {
    print('Level3: $this.level3Data');
    return _Level3State();
  }
}

class _Level3State extends State<Level3> {
  // String level3Data;
  // Function setTextField;

  @override
  Widget build(BuildContext _) {
    return Column(
      children: <Widget>[
        TextField(
          onChanged: widget.setTextField,
        ),
        Text(widget.level3Data),
      ],
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM