An InheritedWidget
might be the best and cleaner way because:
- it gives you the advantage of scoping your variable (I know, you need them globe, so that's not your concern, for now).
- you can rebuild it under some circumstances via the
updateShouldNotify
. When rebuilding an InheritedWidget
you rebuild all the widgets that are referencing its properties.
- it's cleaner than global variables, because you have more control over them and you can also implement some "global" methods that leverage some private variables. It's still a class, after all.
- the access has
O(1)
complexity since Flutter indexes InheritedWidget
implementation, allowing efficient access through the ancestorInheritedElementForWidgetOfExactType
method from context
.
That said, SharedPreferences
is a big no since you'd be doing a lot of disk I/O, which has a lot worse performance than operating in RAM. Plus, you'd need a lot of boilerplate to manage the temporary nature of your variables.
As for global variables, I think they don't give you the same agility of an InheritedWidget
and I don't think that they're a good practice.
Talking about InheritedWidget
, for "dynamic" stuff you might not use it plain, since its variables should be immutable (the class is marked as immutable
, so all of your members should be final).
A clean way to work around this is well explained here. Basically the AppState
are your global variables.
EDIT as @Rémi Rousselet pointed out, telling that ancestorInheritedElementForWidgetOfExactType
has O(1)
complexity is a bit of a stretch, since the lookup is performed on an HashMap
, which has O(1)
complexity for the best case, O(n)
in the worst case.
It's still an efficient way since it doesn't traverse the whole widget tree looking for it.