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

useEffect's disposer should be called before update #335

Open
jeiea opened this issue Dec 15, 2022 · 6 comments
Open

useEffect's disposer should be called before update #335

jeiea opened this issue Dec 15, 2022 · 6 comments
Assignees
Labels
enhancement New feature or request

Comments

@jeiea
Copy link
Contributor

jeiea commented Dec 15, 2022

What I did and description

I don't know whether it is a bug but I'll explain it first.

I thought dispose function (printing unmount in the following code) should be called first after first mount. But it seems not.

Is it intended?

git clone -b effect_hook https://github.com/jeiea/flutter_example.git

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends HookWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends HookWidget {
  MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final tapped = useState<bool?>(null);
    final logs = useState([]);

    useEffect(() {
      if (tapped.value == true) {
        // logs.value = [...logs.value, 'useEffect tap'];
        print('mount 1: ${logs.value}');
      } else if (tapped.value == false) {
        // logs.value = [...logs.value, 'useEffect tap 2'];
        print('mount 2: ${logs.value}');
      }
      return () {
        // logs.value = [...logs.value, 'useEffect unmount'];
        print('unmount: ${logs.value}');
      };
    }, [tapped.value != true]);

    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              SizedBox(
                width: double.infinity,
                child: ElevatedButton(
                  onPressed: () {
                    print('tap');
                    tapped.value = tapped.value != true;
                  },
                  child: Text('Tap me'),
                ),
              ),
              Expanded(
                child: ListView.builder(
                  itemCount: logs.value.length,
                  itemBuilder: ((context, index) => Text(logs.value[index])),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Expected behavior

flutter: mount 2: []
flutter: tap
flutter: unmount: []
flutter: mount 1: []
flutter: tap
flutter: unmount: []
flutter: mount 2: []

Actual behavior

flutter: mount 2: []
flutter: tap
flutter: mount 1: []
flutter: unmount: []
flutter: tap
flutter: mount 2: []
flutter: unmount: []
@jeiea jeiea added bug Something isn't working needs triage labels Dec 15, 2022
@rrousselGit
Copy link
Owner

Not a bug, but that could be a reasonable change.

@rrousselGit rrousselGit added enhancement New feature or request and removed bug Something isn't working needs triage labels Dec 15, 2022
@jeiea
Copy link
Contributor Author

jeiea commented Dec 15, 2022

AFAIK react follow this. It's surprising to me that I didn't know this until now.

@jeiea
Copy link
Contributor Author

jeiea commented Dec 15, 2022

It may be a breaking change but if I make a PR then it can be merged?

@rrousselGit
Copy link
Owner

Honestly I'm not sure. If that's how React behaves. there's some value in keeping it that way. And nobody complained so far either.

If this gets a bunch of 👍, sure. But for now I'd prefer to wait for the confirmation that other people want this too.

@rrousselGit rrousselGit self-assigned this May 10, 2023
@kenNg1
Copy link

kenNg1 commented May 30, 2023

@jeiea Can you reproduce this code in React and share so that we can be certain it's inconsistent?

@jeiea
Copy link
Contributor Author

jeiea commented May 30, 2023

Is the stackoverflow answer enough?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants