rrousselGit / flutter_hooks

React hooks for Flutter. Hooks are a new kind of object that manages a Widget life-cycles. They are used to increase code sharing between widgets and as a complete replacement for StatefulWidget.
MIT License
3.06k stars 175 forks source link

Feature Request: `useListener` hook #389

Open gruvw opened 8 months ago

gruvw commented 8 months ago

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:

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,
]);
rrousselGit commented 8 months ago

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 :)

gruvw commented 8 months ago

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 ?

rrousselGit commented 8 months ago

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.