use-once-constructors-once-provider

Same as use_once_constructors_once_provider in Pyramid Lint

Path
lint/correctness/use-once-constructors-once-provider
Default
Off, opt in
Origin
Pyramid Lint
Domain
flutter
Rule
497 of 512
flutter

Require Riverpod once-providers to be created through .once().

Flags a direct invocation of OnceProvider, FutureProvider, or StateProvider — for example OnceProvider(...) — where the .once() factory should be used instead. The .once() form constructs the provider's value a single time rather than rebuilding it on each read, which is the intended lifecycle for these providers; calling the constructor directly opts out of it. Calls already written as Provider.once(...) are accepted, and explicit new constructions and explicit or implicit const contexts are left alone. Checks calls throughout declarations, including initializers, callbacks, collection literals, conditions, and nested call receivers.

Invalid

example.dartdart
import 'package:riverpod/riverpod.dart';

// Bad: OnceProvider without .once() factory

class MyService {
  String getName() => 'service';
}

final serviceProvider = OnceProvider(
  (ref) => MyService(),
);

final anotherProvider = OnceProvider<String>(
  (ref) => 'value',
);

final badPattern = OnceProvider(
  create: (ref) => MyService(),
);

final futureProvider = FutureProvider(
  (ref) async => 'async value',
);

final stateProvider = StateProvider(
  (ref) => 42,
);

// Bad: provider constructed inside constructor arguments
class Holder {
  final Object provider;
  const Holder(this.provider);
}

final nested = new Holder(OnceProvider(
  (ref) => MyService(),
));
Use the `.once()` factory method for `OnceProvider` and similar Riverpod providers.
8
9final serviceProvider = OnceProvider(
Use the `.once()` factory method for `OnceProvider` and similar Riverpod providers.
12
13final anotherProvider = OnceProvider<String>(
Use the `.once()` factory method for `OnceProvider` and similar Riverpod providers.
16
17final badPattern = OnceProvider(
Use the `.once()` factory method for `OnceProvider` and similar Riverpod providers.
20
21final futureProvider = FutureProvider(
Use the `.once()` factory method for `OnceProvider` and similar Riverpod providers.
24
25final stateProvider = StateProvider(
Use the `.once()` factory method for `OnceProvider` and similar Riverpod providers.
34
35final nested = new Holder(OnceProvider(

Valid

example.dartdart
import 'package:riverpod/riverpod.dart';

// Good: OnceProvider with .once() factory

class MyService {
  String getName() => 'service';
}

final serviceProvider = OnceProvider.once(
  (ref) => MyService(),
);

final anotherProvider = OnceProvider<String>.once(
  (ref) => 'value',
);

final goodPattern = OnceProvider.once(
  create: (ref) => MyService(),
);

final futureProvider = FutureProvider.once(
  (ref) async => 'async value',
);

final stateProvider = StateProvider.once(
  (ref) => 0,
);

// Regular providers (not OnceProvider-related) are fine
final regularProvider = Provider(
  (ref) => 'regular',
);

// OnceProvider variants with .once()
final withTypeParam = OnceProvider<MyService>.once(
  (ref) => MyService(),
);

// Different provider type entirely
final changeNotifierProvider = ChangeNotifierProvider(
  (ref) => MyChangeNotifier(),
);

Configure use-once-constructors-once-provider

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "use-once-constructors-once-provider": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/correctness/use-once-constructors-once-provider: <reason>
  • use-ref-and-state-synchronouslyrecommendedriverpod

    Flags notifier ref and state accesses after an async gap without ref.mounted.

  • use-ref-read-synchronouslyrecommendedriverpod

    Flags Riverpod WidgetRef.read calls after an async gap without a mounted guard.

  • use-setstate-synchronouslyrecommendedflutter

    Require a mounted check before calling setState after an async gap.

  • valid-regexpsvalid_regexpsrecommended

    Disallow statically known invalid dart:core regular expressions.

  • void-checksvoid_checksrecommended

    Don't pass or assign values to void (or FutureOr<void>) locations.

  • add-equatable-propsrecommendedequatable

    Flags concrete Equatable subclasses that do not declare an instance props property.

  • always-pass-global-keyflutter

    Keep GlobalKeys stable and pass owned State fields to widgets.

  • always-remove-listenerrecommendedflutter

    Requires Flutter Listenable registrations in State to be removed.