Skip to content

Riverpod 3.0: Proposal: Remove or Reconsider the only_use_keep_alive_inside_keep_alive lint #4334

@taiju59

Description

@taiju59

Is your feature request related to a problem? Please describe.

Yes. When resolving the only_use_keep_alive_inside_keep_alive lint, developers have two options:

A. Change the consumer provider from keepAlive to autoDispose.
B. Change the consumed provider from autoDispose to keepAlive.

This proposal focuses on the problems that arise when a developer must choose option B. Being forced to change the consumed provider to keepAlive can be problematic for the following reasons:

  • It changes behavior for other consumers: A provider becoming keepAlive changes its behavior for all other consumers that depend on its autoDispose nature.
  • It misplaces the responsibility: Even if a provider is effectively kept alive by a keepAlive consumer, that is a consequence of the consumer's needs. Declaring the keepAlive setting in the consumed provider's code is not the right place for that responsibility.
  • It discourages a disposable-by-default design: The lint encourages making more providers keepAlive than architecturally necessary, which can lead to a less memory-efficient design.

Describe the solution you'd like

Remove the only_use_keep_alive_inside_keep_alive lint.

A keepAlive provider keeping an autoDispose provider alive is a predictable and often desirable feature, not a bug that needs a warning.

Describe alternatives you've considered

Modify the only_use_keep_alive_inside_keep_alive lint to ignore ref.read calls.

ref.read does not create a permanent subscription, and the provider is disposed afterward. Excluding it from the lint would solve the most common cases where this warning feels incorrect.

Additional context

This proposal follows a discussion here: #4329

Sample Code

@Riverpod(keepAlive: true)
class KeepAliveNotifier extends _$KeepAliveNotifier {
  @override
  int build() {
    // Main proposal: allow this `ref.watch`, `ref.listen`, `ref.read` call without a warning.
    ref.watch(nonKeepAliveProvider);
    return 0;
  }

  void func() {
    // Alternative proposal: make the lint ignore `ref.read` calls.
    ref.read(nonKeepAliveProvider);
  }
}

@riverpod
int nonKeepAlive(Ref ref) => 0;

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions