flutterdartstatefulwidgetpass-data

Passing Data to a Stateful Widget in Flutter


I'm wondering what the recommended way of passing data to a stateful widget, while creating it, is.

The two styles I've seen are:

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;
  }
}

This method keeps a value both in ServerInfo and _ServerInfoState, which seems a bit wasteful.

The other method is to use 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;
    }
}

This seems a bit backwards as the state is no longer stored in _ServerInfoSate but instead in the widget.

Is there a best practice for this?


Solution

  • Don't pass parameters to State using it's constructor. You should only access the parameters using this.widget.myField.

    Not only editing the constructor requires a lot of manual work ; it doesn't bring anything. There's no reason to duplicate all the fields of Widget.

    EDIT :

    Here's an example:

    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")
        );
      }
    }