How to change a State of a StatefulWidget inside a StatelessWidget? How to change a State of a StatefulWidget inside a StatelessWidget? dart dart

How to change a State of a StatefulWidget inside a StatelessWidget?


I have approached this problem by initializing the _TestTextState as the final property of the TestText widget which allows to simply update the state when the change button is pressed. It seems like a simple solution but I'm not sure whether it's a good practice.

import 'package:flutter/material.dart';void main() => runApp(new MyApp());class MyApp extends StatelessWidget {  // This widget is the root of your application.  @override  Widget build(BuildContext context) {    return new MaterialApp(      title: 'Test app',      home: new Scaffold(        appBar: new AppBar(          title: new Text("Test"),        ),        body: new Test(),      ),    );  }}class Test extends StatelessWidget {  final _TestText text = new _TestText();  @override  Widget build(BuildContext context) {    return new Column(        children: [          text,          new RaisedButton(            child: new Text("change"),            onPressed: () => text.update(),          ),        ]    );  }}class TestText extends StatefulWidget {  final _TestTextState state = new _TestTextState();  void update() {    state.change();  }  @override  _TestTextState createState() => state;}class _TestTextState extends State<TestText> {  String text = "original";  void change() {    setState(() {      this.text = this.text == "original" ? "changed" : "original";    });  }  @override  Widget build(BuildContext context) {    return new Text(this.text);  }}


thier is no way to do so. any how you have to convert your StatelessWidget to StatefulWidget.


Solution based on your existing code

class Test extends StatelessWidget {  final StreamController<String> streamController = StreamController<String>.broadcast();  @override  Widget build(BuildContext context) {    final TestText testText = TestText(streamController.stream);    return new Column(children: [      testText,      new RaisedButton(        child: Text("change"),        onPressed: () {          String text = testText.text == "original" ? "changed" : "original";          streamController.add(text);        },      ),    ]);  }}class TestText extends StatefulWidget {  TestText(this.stream);  final Stream<String> stream;  String text = "original";  @override  TestTextState createState() => new TestTextState();}class TestTextState extends State<TestText> {  @override  void initState() {    widget.stream.listen((str) {      setState(() {        widget.text = str;      });    });    super.initState();  }  @override  Widget build(BuildContext context) {    return Text(widget.text);  }}

But it's not the best idea - to use non-final field inside Stateful Widget

P.S.You can also use this - scoped_model