flutter_hooks icon indicating copy to clipboard operation
flutter_hooks copied to clipboard

Feature Request: `useListener` hook

Open gruvw opened this issue 2 years ago • 3 comments
trafficstars

Is your feature request related to a problem? Please describe.

When using Listenable with useEffect it can be a bit cumbersome to always repeat the same boilerplate off addListener and removeListener again and again:

  • Having to call keys.length times addListener
  • Duplication of key in keys and key.addListener(...) for each key
  • Extra level of indentation when writing the listener inside the useEffect closure

Describe the solution you'd like

Add a useListener hook.

void useListener(void Function() listener, List<Listenable> listenables) {
  useEffect(() {
    final listenable = Listenable.merge(listenables);
    listenable.addListener(listener);

    return () => listenable.removeListener(listener);
  }, listenables);
}

Additional context

This would be very useful to bind values when some controller changes:

final nameError = useState<String?>(null);
final nameController = useTextEditingController();

useListener(() {
  final validation = nameValidation(offlineNameController.text);
  nameError.value = validation.nameError;
}, [nameController]);

and even when it depends on multiple controllers like:

final activeTab = useState(_initialTab);
final primaryTabController = useTabController(
  initialLength: Tabs.primaryTabLength,
  initialIndex: activeTab.value.primaryTabIndex,
);
final secondaryTabController = useTabController(
  initialLength: Tabs.secondaryTabLength,
  initialIndex: activeTab.value.secondaryTabIndex,
);

useListener(() {
  activeTab.value = Tabs.of(
    primaryTabController.index,
    secondaryTabController.index,
  );
}, [
  primaryTabController,
  secondaryTabController,
]);

gruvw avatar Oct 22 '23 22:10 gruvw

The naming would more more "useOnListenableChange", like "useOnStreamChange" And it would take a single listenable, not a list of listenable.

Otherwise LGTM. Feel free to make a PR if you want to :)

rrousselGit avatar Oct 23 '23 09:10 rrousselGit

Ok sure I will try and make a PR! Let me know if I mess up something doing so as it's only my second one :)

However why not a list of listenables ? It's more convenient isn't it ?

gruvw avatar Oct 23 '23 09:10 gruvw

Folks wanting to listen to multiple listenables can use the hook multiple times or use Listenable.merge

It's rare that they'll want to listen to multiple listenables at once.

rrousselGit avatar Oct 23 '23 10:10 rrousselGit