2

I need to store some data that should be available everywhere on my application. So far, I know three methods to do it:

  • Create a special file to make variable global (Global Variables in Dart)
  • Use shared preference (here I just want to access the data not necessarily to store it forever)
  • And InheritedWidget

I would like to know which solution (or another one that I don't know) is the best in matters of performance and easy to implement.

AmazingBite
  • 302
  • 2
  • 16

1 Answers1

9

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.

AmazingBite
  • 302
  • 2
  • 16
magicleon94
  • 4,887
  • 2
  • 24
  • 53
  • 2
    O(1) for InheritedWidgets is a bit of a lie. It doesn't traverse the widget tree, but it still looks into a hash map. But yeah, I'll take InheritedWidgets over globals all the time. – Rémi Rousselet Aug 12 '19 at 12:51
  • Yeah you're right, O(1) is the best case scenario. I'm going to edit that, thanks! – magicleon94 Aug 12 '19 at 12:55
  • 1
    InheritedWidget is awesome for global state, however, it's not recommended by any means to have a unique inherited widget because it will call ALL of the build methods. I generally use a root inherited widget for data that doesn't change that often, and then below that i use multiple inherited widgets with selective data – RegularGuy Aug 09 '20 at 16:19