ステートフルウィジェットにデータを渡す


113

ステートフルウィジェットを作成するときに、それをデータに渡すための推奨される方法は何でしょうか。

私が見た2つのスタイルは次のとおりです。

class ServerInfo extends StatefulWidget {

  Server _server;

  ServerInfo(Server server) {
    this._server = server;
  }

  @override
    State<StatefulWidget> createState() => new _ServerInfoState(_server);
}

class _ServerInfoState extends State<ServerInfo> {
  Server _server;

  _ServerInfoState(Server server) {
    this._server = server;
  }
}

この方法は、両方値を保持ServerInfoし、_ServerInfoState少し無駄思われます。

他の方法は使用することwidget._serverです:

class ServerInfo extends StatefulWidget {

  Server _server;

  ServerInfo(Server server) {
    this._server = server;
  }

  @override
    State<StatefulWidget> createState() => new _ServerInfoState();
}

class _ServerInfoState extends State<ServerInfo> {
  @override
    Widget build(BuildContext context) {
      widget._server = "10"; // Do something we the server value
      return null;
    }
}

状態はもはや_ServerInfoSateウィジェットに保存されず、代わりに保存されるため、これは少し逆のようです。

このためのベストプラクティスはありますか?


3
コンストラクタはに減らすことができるServerInfo(this._server);
ギュンターZöchbauer

この質問は以前に尋ねられました:stackoverflow.com/questions/50428708/…–
Blasanka


この回答は、このいずれかの前に1ヶ月追加されます:stackoverflow.com/questions/50428708/...
Blasanka

回答:


230

Stateコンストラクタの使用にパラメータを渡さないでください。これらにアクセスするには、を使用する必要がありますthis.widget.myField

コンストラクタを編集するだけで多くの手作業が必要になるだけではありません。それは何ももたらしません。のすべてのフィールドを複製する理由はありませんWidget

編集:

次に例を示します。

class ServerIpText extends StatefulWidget {
  final String serverIP;

  const ServerIpText ({ Key key, this.serverIP }): super(key: key);

  @override
  _ServerIpTextState createState() => _ServerIpTextState();
}

class _ServerIpTextState extends State<ServerIpText> {
  @override
  Widget build(BuildContext context) {
    return Text(widget.serverIP);
  }
}

class AnotherClass extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ServerIpText(serverIP: "127.0.0.1")
    );
  }
}

23
さらにコメントすると、コンストラクターを介してStateオブジェクトに渡したものはすべて更新されません。
ジョナウィリアムズ

4
そして、私はコメントを理解しています。「コンストラクターを使用してパラメーターをStateに渡さないでください」。では、どのようにしてパラメータを状態に渡すのでしょうか?
KhoPhi 2018

6
@Rexford は、フィールドを使用Stateしてのすべてのプロパティへのアクセスとして既に。Statefulwidget
レミRousselet

4
@RémiRousseletfooを使用してテキストフィールドを事前入力し、ユーザーがそれを編集できるようにするにはどうすればよいですか。状態に別のfooプロパティも追加する必要がありますか?
Saifiが2018

1
@ user6638204状態に別のfooプロパティを作成し、状態をオーバーライドvoid initState()して初期値を設定できます。 例として、このスレッドオプションCを確認してください。
ジョセフチェン

30

最善の方法は、コンストラクターを使用してStateクラスにパラメーターを渡さないことです。Stateクラスではを使用して簡単にアクセスできますwidget.myField

例えば

class UserData extends StatefulWidget {
  final String clientName;
  final int clientID;
  const UserData(this.clientName,this.clientID);

  @override
  UserDataState createState() => UserDataState();
}

class UserDataState extends State<UserData> {
  @override
  Widget build(BuildContext context) {
    // Here you direct access using widget
    return Text(widget.clientName); 
  }
}

画面をナビゲートするときにデータを渡します。

 Navigator.of(context).push(MaterialPageRoute(builder: (context) => UserData("WonderClientName",132)));

8

@RémiRousseletのアンサーと@ user6638204の質問に基づいて、初期値を渡し、後でその状態でそれらを更新できるようにする場合は、別の答え:

class MyStateful extends StatefulWidget {
  final String foo;

  const MyStateful({Key key, this.foo}): super(key: key);

  @override
  _MyStatefulState createState() => _MyStatefulState(foo: this.foo);
}

class _MyStatefulState extends State<MyStateful> {
  String foo;

  _MyStatefulState({this.foo});

  @override
  Widget build(BuildContext context) {
    return Text(foo);
  }
}

7
initStateを直接使用して、foo = widget.fooのようなことを行うことができます。コンストラクターに渡す必要はありません
Aqib

これに引数を渡す方法は?
Steev James

@SteevJamesウィジェットにMyStatefulはオプションの名前付きパラメーター(プロパティ)が1つあります。呼び出すことでこのウィジェットを作成できますMyStateful(foo: "my string",)
Kirill Karmazin

@AqibはinitState、次のシナリオの問題を解決しません。たとえば、空のパラメーターを使用してStatefullウィジェットを作成し、データのロードを待機しています。データがロードされたら、ステートフルウィジェットを新しいデータで更新します。この場合、MyStatefull(newData)を呼び出すinitState()と、呼び出されません。この場合、didUpdateWidget(MyStatefull oldWidget)呼び出されると、あなたは、引数からあなたのデータを比較する必要があるだろうoldWidget.getData()widget.data、それは同じではない場合-コールsetState()ウィジェットを再構築します。
Kirill Karmazin

1
@ kirill-karmazinステートレスウィジェットソリューションについて詳しく説明できますか?代わりに何を使いますか?Flutterチームのベストプラクティスですか?ありがとう
camillo777

4

初期値を渡すため(コンストラクタに何も渡さない)

class MyStateful extends StatefulWidget {
  final String foo;

  const MyStateful({Key key, this.foo}): super(key: key);

  @override
  _MyStatefulState createState() => _MyStatefulState();
}

class _MyStatefulState extends State<MyStateful> {
  @override
  void initState(){
    super.initState();
    // you can use this.widget.foo here
  }

  @override
  Widget build(BuildContext context) {
    return Text(foo);
  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.