Skip to main content

vs Flutter Hooks 🛠️

Utopia Hooks builds on the concepts introduced by Flutter Hooks. The main breakthrough comes from decoupling them from the Flutter framework itself by creating an additional abstraction layer.

This allows hooks to be used in various contexts, covering all use-cases required for a complete mobile application architecture including not only local, but also global states, as well as unit & integration-testing.

Pain Points

Architecture Goals

Flutter Hooks at their purest form are slightly optimized way of writing Stateless/Stateful code, which is not suitable for projects based on Clean Architecture standards and often are used only as a local state helper for solutions like Flutter Riverpod.

That’s the opposite to what UtopiaHooks library is designed to do. It introduces a comprehensive and holistic approach to the architecture, making other alternatives redundant.

Testing

Original Flutter Hooks are inherently coupled with Flutter Widgets. It comes with a significant drawback. The business-logic layer effectively cannot be covered with unit/integration tests. By decoupling those dependencies we were able to achieve completely testable environment.

Conditional Hooks

We have introduced conditional hook statements for the better state composability. In the original approach creating conditional hooks (if/else) is impossible. This results with better code clarity and reduces need for weird workarounds (e.g. in dynamic text field builders).

Edge Cases

Flutter Hooks based architecture comes with few major drawbacks. For example, since they are dependent on Flutter, it is impossible to update state of the application in the background. For example, that makes it unsuitable for geolocation related projects or communicators.

Architecture Overview



Abstraction Layer: HookContext

HookWidget allows hooks to be used in any Flutter Widget. This provides functionality identical to Flutter Hooks, but also allows for out-of-the-box integration with Global States.

Local State: HookWidget

As mentioned, the key difference of the architecture is an additional abstraction layer. By providing a unified, flutter-independent environment in which hooks can be used, it allows the library to provide a set of universal hooks that can be used in every dart environment - even completely unrelated to Flutter.

Unit Testing: SimpleHookContext

SimpleHookContext is a bare-bones environment in which individual hooks can be easily initialized and unit-tested. Its simplicity makes unit-tests remarkably straightforward and readable - it gets as easy as testing a simple function.

Integration Testing: HookProviderContainer

HookProviderContainer allows cross-communication of multiple hook-based global and local states. It’s decoupled from Flutter, which has an important consequence - global states can work seamlessly, even when Flutter is not rendering anything (e.g. because application is in the background or has not fully started yet). Additionally, this serves as an integration-testing environment for global states.

Global State: HookProviderContainerWidget

HookProviderContainerWidgets connects the HookProviderContainer back to Flutter, allowing global states to be consumed by local states. It does all of this without compromising on its benefits (including seamless background execution).