8

Currently exploring functional_widgets and flutter_hooks. Having same idea with reactjs I'm fetching data with the following code.

@hwidget
Widget homeScreen(BuildContext context) {
  TodoListProvider model = Provider.of<TodoListProvider>(context);
  useEffect(() {
    print('effect');
    model.fetchList();
    return () => {};
  }, []);
  return Scaffold(
    appBar: _buildAppbar(context, model),
    bottomNavigationBar: _buildBottomNav(context, model),
    floatingActionButton: _buildFloatingAction(context),
    body: PageTransitionSwitcher(
      duration: const Duration(milliseconds: 300),
      reverse: model.reverse,
      transitionBuilder: (
        Widget child,
        Animation<double> animation,
        Animation<double> secondaryAnimation,
      ) {
        return SharedAxisTransition(
          child: child,
          animation: animation,
          secondaryAnimation: secondaryAnimation,
          transitionType: SharedAxisTransitionType.horizontal,
        );
      },
      child: _getCurrentTab(model.currentIndex),
    ),
  );
}

I don't think this is the right way since it's throwing an error.enter image description here

Jasper Bernales
  • 1,601
  • 1
  • 11
  • 16
  • 1
    `return () => {}` probably doesn't mean what you think it means. You're returning a function that returns an empty Map when called. I *think* you meant `return () {}`. Remember, it's arrow or body block. Not both. :) – Randal Schwartz Jan 31 '21 at 02:27

3 Answers3

21

The issue with:

  useEffect(() {
    model.fetchList();
  }, []);

is that fetchList is called synchronously inside build and modify an ancestor widget, which is not good.

You can wrap the fetchList call in a microtask:

  useEffect(() {
    Future.microtask(() => model.fetchList());
  }, []);
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
7

I know this question is old. But I hope my answer can help someone. I solved the problem by making the function call in the next frame

useEffect(() {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      model.fetchList();
    }
}, []);

Aimn Blbol
  • 907
  • 11
  • 20
0

Personally I have used useEffect() to make init calls in cubits, like so:

final cubit = useCubit<BooksListCubit>();
final state = useCubitBuilder<BooksListCubit, BooksListPageState>(cubit);

useEffect(
  () {
    cubit.init();
    return null;
  },
  [cubit],
);

More on this in my extensive Flutter cubits + hooks + Hive tutorial.

lomza
  • 9,412
  • 15
  • 70
  • 85