Flutter Riverpod : The member 'state' can only be used within instance members of subclasses of 'package:state_notifier/state_notifier.dart'

Viewed 1902

I have simple example about toggle widget,my expectation after click button i show circularProgressIndicator then after 3 second i showing Text. For my example i use riverpod_hooks and flutter_hooks.

LoadingProvider

class IsLoading extends StateNotifier<bool> {
  IsLoading() : super(false);
  void toggleLoading(bool value) => state = value;
}

final isLoadingProvider = StateNotifierProvider((ref) => IsLoading());

Main.dart

class TestingApp extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final IsLoading isLoading = useProvider(isLoadingProvider);
    return Scaffold(
      body: Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Center(
              child: isLoading.state ? CircularProgressIndicator() : Text('This Is Your Data'),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: FlatButton(
                  onPressed: () => showLoading(isLoading), child: Text('Toggle Loading')),
            ),
          ],
        ),
      ),
    );
  }

  void showLoading(IsLoading isLoading) async {
    isLoading.toggleLoading(true);
    print("Proses");
    await Future.delayed(const Duration(seconds: 3));
    print("Done");
    isLoading.toggleLoading(false);
  }
}

But when i press the button , it's not show progressIndicator and still showing the text and i got this warning :
The member 'state' can only be used within instance members of subclasses of 'package:state_notifier/state_notifier.dart'.

I missed something ?

My source code following the documentation like this :

enter image description here

2 Answers

It says right there that it won’t trigger the method to rebuild when you call increment like that.

so instead of isLoading.toggleLoading(true) call with a read method so it can rebuild the state like that isLoading.read(context).toggleLoading(true)

Provide two types for your StateNotifierProvider, the type of class you are returning and the state the class has.

class IsLoading extends StateNotifier<bool> {
  IsLoading() : super(false);
  void toggleLoading(bool value) => state = value;
}

final isLoadingProvider =
    StateNotifierProvider<IsLoading, bool>((ref) => IsLoading());

in your build method (of a ConsumerStateWidget) use:

final isLoading = ref.watch(isLoadingProvider);
return Scaffold(body: Center(child:
isLoading ? CircularProgressIndicator() : Text('This Is Your Data'),))
Related