flutterdartsetstatestateful

Flutter setState function doesn't work when used to change class member


i have the following codes,

class mWidget extends StatefulWidget {
  mWidget({super.key, required this.text});
  String text;

  @override
  State<mWidget> createState() => _mWidgetState();
}

class _mWidgetState extends State<mWidget> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(widget.text),
    );
  }
}

This is my custom widget,

class _MainState extends State<Main> {
  var n = mWidget(text: "Hi");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          n,
          ElevatedButton(
            onPressed: () {
              setState(() {
                n.text = "Hello";
              });
            },
            child: Text("Click me"),
          ),
        ],
      ),
    );
  }
}

And this is the code in the main.dart file.

The problem is that pressing the button doesn't change the output on the screen unless a hot reload even though I am calling the setState function.

I wonder why is that.

Thanks in advance!


Solution

  • You made a couple of mistakes in this!

    In your code, you made a widget named mWidget and created an instance of it, it is not the right approach to access any widget using an instance, as state of instances cannot be updated.

    You are using the state of mWidget outside of its scope, where it is not accessible.

    You can use keys to achieve what you want. (It is not advisable to use this for large-scale project)

    Here is a small code which can help you to achieve the functionality you want.

    class mWidget extends StatefulWidget {
      mWidget({Key? key, required this.text}) : super(key: key);
      String text;
    
      @override
      State<mWidget> createState() => _mWidgetState();
    }
    
    class _mWidgetState extends State<mWidget> {
      String text = "";
    
      @override
      void initState() {
        text = widget.text;
        super.initState();
      }
    
      void updateValue(String newData) {
        setState(() {
          text = newData;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Center(
          child: Text(text),
        );
      }
    }
    
    
    
    class _Main extends StatefulWidget {
      const _Main({Key? key}) : super(key: key);
    
      @override
      State<_Main> createState() => _MainState();
    }
    
    class _MainState extends State<_Main> {
      GlobalKey<_mWidgetState> _mWidgetStateKey = GlobalKey(); // This is the key declaration of _mWidgetState type
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              mWidget(text: "Hi", key: _mWidgetStateKey),
              ElevatedButton(
                onPressed: () =>
                    _mWidgetStateKey.currentState!.updateValue("Hello"), // Calling the method of _mWidgetState class.
                child: Text("Click me"),
              ),
            ],
          ),
        );
      }
    }