Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should we add a "DON'T" for using hooks after an early return? #439

Closed
btrautmann opened this issue Jul 25, 2024 · 1 comment
Closed

Should we add a "DON'T" for using hooks after an early return? #439

btrautmann opened this issue Jul 25, 2024 · 1 comment

Comments

@btrautmann
Copy link

Describe what scenario you think is uncovered by the existing examples/articles

The README does a good job highlighting some of the footguns possible when using hooks. Specifically, it says to not use them in a conditional, but an implicit "conditional" exists: early returns. Consider the following:

class MainApp extends HookWidget {
const MainApp({super.key});

@override
Widget build(BuildContext context) {
  if (Random().nextBool()) {
    return Container(
      color: Colors.red,
      child: const SizedBox(
        height: 100,
        width: 100,
      ),
    );
  }

  useEffect(() {
    print('useEffect');
    return null;
  }, []);

  final counter = useState(0);

  return Scaffold(
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          const Text('You have pushed the button this many times:'),
          Text(
            '${counter.value}',
            style: Theme.of(context).textTheme.headlineLarge,
          ),
        ],
      ),
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: () => counter.value++,
      tooltip: 'Increment',
      child: const Icon(Icons.add),
    ),
  );
}
}

This code compiles and seems to run fine, but any time the "hooks codepath" is run (i.e useEffect prints), the counter is re-initialized to 0. If you move the hooks above the early return, things work correctly.

Describe why existing examples/articles do not cover this case

The react hooks documentation calls out:

Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns. You can only call Hooks while React is rendering a function component:

We can probably have more parity by calling out the same in the README.

@rrousselGit
Copy link
Owner

It's considered a feature. flutter_hooks does support early returns.

The state after an early return getting destroyed when reaching the early return makes sense generally. View it as releasing unused resources.
In the same sense, effects and controllers would be disposed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants