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

Listeners are not removed when provider refreshes #3738

Closed
Colton127 opened this issue Sep 12, 2024 · 1 comment
Closed

Listeners are not removed when provider refreshes #3738

Colton127 opened this issue Sep 12, 2024 · 1 comment
Assignees
Labels
bug Something isn't working needs triage

Comments

@Colton127
Copy link

Describe the bug
Riverpod documentation states:

Listeners will automatically be removed when the provider rebuilds (such as when a provider listened with [watch] changes).

However, listeners remain alive and even continuously rebuild (without removing prior instances) using the code below.

To Reproduce

import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final printCountNotifierProvider = NotifierProvider<PrintCountNotifier, bool>(PrintCountNotifier.new);

class PrintCountNotifier extends Notifier<bool> {
  bool _printCount = false;

  @override
  bool build() {
    if (!_printCount) return false;
    ref.listen(countNotifierProvider, (previous, next) {
      print('PrintCount: $_printCount | Count: $next');
    });
    return true;
  }

  void toggle() {
    _printCount = !_printCount;
    state = build();
  }
}

final countNotifierProvider = NotifierProvider<CountNotifier, int>(CountNotifier.new);

class CountNotifier extends Notifier<int> {
  @override
  int build() {
    Timer.periodic(const Duration(seconds: 1), (timer) {
      state = state + 1;
    });
    return 0;
  }
}


Expected behavior
Expected: countNotifierProvider listener should be automatically removed when printCountNotifierProvider rebuilds.

Actual output:

PrintCount: true | Count: 1
PrintCount: true | Count: 2
PrintCount: true | Count: 3
PrintCount: true | Count: 4
PrintCount: true | Count: 5
PrintCount: true | Count: 6
PrintCount: true | Count: 7
PrintCount: true | Count: 8
PrintCount: true | Count: 9
PrintCount: false | Count: 10
PrintCount: false | Count: 11
PrintCount: false | Count: 12
PrintCount: false | Count: 13
PrintCount: false | Count: 14
PrintCount: false | Count: 15
PrintCount: false | Count: 16
PrintCount: false | Count: 17
PrintCount: false | Count: 18
PrintCount: false | Count: 19
PrintCount: false | Count: 20
PrintCount: false | Count: 21
PrintCount: false | Count: 22
PrintCount: false | Count: 23
PrintCount: false | Count: 24
PrintCount: false | Count: 25
PrintCount: false | Count: 26
PrintCount: false | Count: 27
PrintCount: false | Count: 28
PrintCount: false | Count: 29
PrintCount: false | Count: 30
PrintCount: false | Count: 31
PrintCount: true | Count: 32
PrintCount: true | Count: 32
PrintCount: true | Count: 33
PrintCount: true | Count: 33
PrintCount: true | Count: 34
PrintCount: true | Count: 34
PrintCount: true | Count: 35
PrintCount: true | Count: 35

Notice how each number is printed twice at the end. The previous listener is never removed, even though a new one is created.

@Colton127 Colton127 added bug Something isn't working needs triage labels Sep 12, 2024
@rrousselGit
Copy link
Owner

state = build();

That's not legal. Only Riverpod should call build.
Your provider didn't really rebuild.

If you want a provider to rebuild itself, use ref.invalidateSelf(). Then Riverpod will reinvoke build, and listeners will be updated accordingly

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs triage
Projects
None yet
Development

No branches or pull requests

2 participants