Home > Net >  How to get the State<> instance inside of its StatefulWidget?
How to get the State<> instance inside of its StatefulWidget?

Time:07-16

I have an unusual use case where I'd like to add a getter to a StatefulWidget class that accesses its State instance. Something like this:

class Foo extends StatefulWidget {
  Foo({super.key});

  int get bar => SomethingThatGetsFooState.bar;

  @override
  State<Foo> createState() => _FooState();
}

class _FooState extends State<Foo> {
  int bar = 42;

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

Does SomethingThatGetsFooState exist?

CodePudding user response:

I wonder, if your approach is the right way.

Flutter's way isn't 'Ask something about its state'

Flutter is much more like this: 'The consumer of a Widget passes something to another Widget, which the other Widget e.g. calls in case of certain situations (e.g. value change).'

Approach 1

You map pass a Callback Function to Foo and pass that along to _FooState.

If something special happens inside _FooState, you may call the callback and thus pass some value back to the provider of the Callback.

Approach 2

Probably use a state management solution like Flutter Redux. Using Flutter Redux, you establish a state store somewhere at the top of the widget tree, e.g. in MaterialApp.

Then you subscribe to the store at certain other locations, where dependent widgets exist, which need to update accordingly.

In one project I created certain Action classes, which I send to certain so called reducers of those states, to perform a change on the state:

StoreProvider.of<EModel>(context).dispatch( SaveToFileAction()) 

This call finds the relevant EModel state and asks it to perform the SaveToFileAction().

This way, a calling Widget not even needs to know, who is responsible for the Action.

The responsible Widget can even be moved around the widget tree - and the application still works. The initiator of SaveToFileAction() and the receiver are decoupled. The receiver you told a coordination 'Tell me, if someone tried to ask me for something.'

Could your provide some further details? Describe the usage pattern?

CodePudding user response:

@SteAp is correct for suggesting there's a code smell in my OP. Typically there's no need to access State thru its StatefulWidget. But as I responded to his post, I'm fleshing out the first pass at a state management package, so it's an unusual case. Once I get it working, I'll revisit.

Below worked without Flutter complaining.

class _IntHolder {
  int value;
}

class Foo extends StatefulWidget {
  Foo({super.key});

  final _intHolder = _IntHolder();
  int get bar => _intHolder.value;

  @override
  State<Foo> createState() => _FooState();
}

class _FooState extends State<Foo> {
  @override
  Widget build(BuildContext context) {
    widget._intHolder.value = 42;
    return Container();
  }
}
  • Related