useMemoized is a hook in Flutter Hooks, a package that introduces the concept of hooks from React into Flutter.

It’s used for creating memoized values, which are values that are computed only when one of their dependencies change. This is useful for optimizing performance by avoiding unnecessary computations.

Create a HookWidget:

To use hooks, your widget must be a HookWidget. Change your widget to extend HookWidget:

class MyWidget extends HookWidget {
  @override
  Widget build(BuildContext context) {
    // ...
  }
}

Use ‘useMemoized’:

Inside your build method, use useMemoized to create a memoized value. The first argument is a function that returns the value you want to memoize. The second argument is a list of dependencies; the memoized value will only be recomputed when any of these dependencies change.

final memoizedValue = useMemoized(() {
  // Expensive computation or logic here
  return computedValue;
}, [dependency1, dependency2]); // List of dependencies

Real World Example:

Let’s consider a more real-world example where useMemoized can be effectively utilized in a Flutter Hooks application. Imagine you have an app that displays a filtered list of products based on user input. The list filtering process is computationally expensive, so you want to memoize the filtered list to avoid unnecessary recalculations whenever the widget rebuilds but the filter criteria haven’t changed.

Here’s how you can implement this:

  1. Set Up the Basic Widget: Create a HookWidget that includes a text field for the user to enter a filter keyword and a list view to display the filtered products.
  2. Use State for User Input: Use useState to manage the state of the user’s input (the filter keyword).
  3. Apply useMemoized for Filtering: Use useMemoized to compute the filtered list of products. The computation should only be redone when the filter keyword changes.
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

class Product {
  final String name;

  Product(this.name);
}

class ProductListWidget extends HookWidget {
  final List<Product> allProducts = [
    Product('Laptop'),
    Product('Smartphone'),
    Product('Tablet'),
    Product('Smartwatch'),
    // ... more products
  ];

  @override
  Widget build(BuildContext context) {
    final filterKeyword = useState('');

    // Memoize the filtered list
    final filteredProducts = useMemoized(() {
      return allProducts
          .where((product) =>
              product.name.toLowerCase().contains(filterKeyword.value.toLowerCase()))
          .toList();
    }, [filterKeyword.value]);

    return Scaffold(
      appBar: AppBar(title: Text('Product List')),
      body: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              onChanged: (value) => filterKeyword.value = value,
              decoration: InputDecoration(
                labelText: 'Filter by name',
                border: OutlineInputBorder(),
              ),
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: filteredProducts.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(filteredProducts[index].name),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

In this example, allProducts is a list of Product objects. The ProductListWidget includes a TextField for the user to enter a filter keyword. The filteredProducts list is computed using useMemoized, which ensures that the filtering process is only executed when the filter keyword changes, thus improving performance by avoiding unnecessary computations.

Happy Coding

Categorized in: