स्टेटफुल विजेट में डेटा पास करना


113

मैं सोच रहा हूं कि डेटा को स्टेटफुल विजेट पर भेजने का अनुशंसित तरीका क्या है, इसे बनाते समय।

मैंने जिन दो शैलियों को देखा है वे हैं:

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);
गुंटर जोचबॉयर

यह प्रश्न पहले पूछा गया है: stackoverflow.com/questions/50428708/…
Blasanka

क्या इससे आपके सवाल का जवाब मिलता है? StatefulWidget में डेटा पास करना और इसे
Flutter

यह उत्तर इससे एक महीने पहले जोड़ा गया है: 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
एक और टिप्पणी, आप जिस किसी भी वस्तु को कंस्ट्रक्टर के माध्यम से पास करते हैं वह कभी अपडेट नहीं होगी!
जोनाह विलियम्स

4
और यहां मैं टिप्पणी नहीं कर रहा हूं। "यह निर्माणकर्ता का उपयोग करके राज्य को पास न करें"। तो मैं राज्य को पैरामीटर कैसे पास करूं?
20

6
@Rexford क्षेत्र का उपयोग करके Stateपहले से ही सभी गुणों तक पहुँच के रूप में । Statefulwidget
Rémi Rousselet 21

4
@ RémiRousselet क्या होगा अगर मैं टेक्स्ट फ़ील्ड को भरने के लिए फू का उपयोग करना चाहता हूं, और फिर भी उपयोगकर्ता को इसे संपादित करने की अनुमति देता है। क्या मुझे राज्य में एक और फू प्रॉपर्टी भी जोड़नी चाहिए?
सैफी ने

1
@ user6638204 आप राज्य में एक और foo संपत्ति बना सकते हैं, और void initState()प्रारंभिक मूल्य निर्धारित करने के लिए राज्य पर ओवरराइड कर सकते हैं । उदाहरण के लिए इस थ्रेड विकल्प C की जाँच करें ।
जोसेफ चेंग

30

सबसे अच्छा तरीका यह है कि यह कंस्ट्रक्टर का उपयोग करके राज्य वर्ग के लिए पैरामीटर पारित न करें। आप आसानी से राज्य वर्ग का उपयोग कर सकते हैं 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's anwser पर और @ 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
हम inooState का उपयोग सीधे foo = widget.foo जैसे कुछ करने के लिए कर सकते हैं, कंस्ट्रक्टर को पास करने की आवश्यकता नहीं है
Aqib

इस पर तर्क कैसे पारित करें?
Steev James

@SteevJames के विजेट MyStatefulमें एक वैकल्पिक नामित पैरामीटर (संपत्ति) है जिसे आप कॉल करके इस विजेट को बना सकते हैंMyStateful(foo: "my string",)
Kirill Karmazin

@ अकीब initStateनिम्नलिखित परिदृश्य में एक समस्या का समाधान नहीं करता है: उदाहरण के लिए, आपने अपना स्टेटफुल विजेट खाली मापदंडों के साथ बनाया है और आप अपने डेटा को लोड करने की प्रतीक्षा कर रहे हैं। जब डेटा लोड हो जाता है तो आप अपने स्टेटफुल विजेट को नए डेटा के साथ अपडेट करना चाहते हैं और इस मामले में जब आप MyStatefull (newData) को कॉल initState()करेंगे तो इसे कॉल नहीं किया जाएगा! इस मामले में didUpdateWidget(MyStatefull oldWidget)बुलाया जाएगा और आप तर्क से अपने डेटा की तुलना करने की आवश्यकता होगी oldWidget.getData()के साथ widget.dataऔर अगर यह एक ही नहीं है - कॉल setState()विजेट के पुनर्निर्माण के लिए।
किरिल कर्माज़िन

1
@ kirill-karmazin क्या आप स्टेटलेस विजेट समाधान पर अधिक विस्तृत कर सकते हैं? इसके बजाय आप क्या उपयोग करेंगे? क्या यह स्पंदन टीम का सबसे अच्छा अभ्यास है? धन्यवाद
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);
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.