s0nerik / context_plus

Convenient BuildContext-based value propagation and observing. Seamlessly integrates with Flutter's built-in observability primitives.
MIT License
32 stars 4 forks source link

Proposal: Possibility to memoize value across rebuilds #5

Closed arthurbcd closed 5 months ago

arthurbcd commented 6 months ago

In the current approach, we have the .watch extension to Future, Stream and Listenable.

What if we also had something like that for functions?

For the Api, maybe even an extension type:

extension type Memoize<T>(T Function() fn) {
final T Function() fn;

T get value => // the fn Function would be called once and the memoized value would be returned across rebuilds.
}

Or some api similar to Hooks.

With that it would be possible to handle Future/Stream functions direct in the build. As of right now, we need to save the Future/Stream state elsewhere.

s0nerik commented 6 months ago

Hey Arthur! What you're describing sounds like a supported use-case for context_ref's Ref.bind() (potentially specifying a key, if the provided Stream/Future should change based on some other value).

Here's how something like that may look like with context_plus:


final _query = Ref<String>();
final _searchResults = Ref<Future<List<Result>>>();

class Example extends StatelessWidget {
  const Example({super.key});

  @override
  Widget build(BuildContext context) {
    final query = _query.of(context); // Provided somewhere else
    _searchResults.bind(context, () => API.fetchResults(query), key: query);
    return const _SearchResults();
  }
}

class _SearchResults extends StatelessWidget {
  const _SearchResults();

  @override
  Widget build(BuildContext context) {
    final searchResultsSnapshot = _searchResults.watch(context);
    ...
  }
}