skip to Main Content

How to handle setState in a function ?

I have 2 functions where the user press a button and i save and load the state of that button whenever i need it ,also i store it in sharedPreference.

I want to move that code :

  Future<void> _loadPrivacyPolicyAcceptance() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      _acceptedPrivacyPolicy = prefs.getBool('acceptedPrivacyPolicy') ?? false;
    });
  }

  Future<void> _savePrivacyPolicyAcceptance(bool accepted) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool('acceptedPrivacyPolicy', accepted);
  }

In a new file where i use only functions and not widgets ,but i can’t use setState without a widget.

How i can handle that behaviour ?

2

Answers


  1. Update

    Thanks to @Yes Dev for his suggestion to use a StateSetter.

    However, it seems the method needs to be implemented as:

    Future<void> loadPrivacyPolicyAcceptance(
      StateSetter setState,
      VoidCallback callback,
    ) async {
      setState(callback);
    }
    

    Thus you call it:

    loadPrivacyPolicyAcceptance(setState, () {
      final prefs = await SharedPreferences.getInstance();
      _acceptedPrivacyPolicy = prefs.getBool('acceptedPrivacyPolicy') ?? false;
    });
    

    Which at some point leads to the issue of not moving the code somewhere else from the widget.


    Although there is no "straightforward" way to move the setState outside of the StatefulWidget class, the same concept can be achieved by following a different state management approach.

    The main goal is to access the state outside the widget class, which can be achieved using the ChangeNotifier class.

    I’d recommend a better understanding of the ChangeNotifier and ChangeNotifierProviderProvider. You could also check: Simple app state management.

    Example:

    1: Create the ChangeNotifier class that contains the global states:

    class GlobalStates extends ChangeNotifier {
      bool _acceptedPrivacyPolicy = false;
      bool get acceptedPrivacyPolicy => _acceptedPrivacyPolicy;
    
      Future<void> loadPrivacyPolicyAcceptance() async {
        // ...
    
        notifyListeners();
      }
    
      Future<void> savePrivacyPolicyAcceptance(bool accepted) async {
        // ...
    
        notifyListeners();
      }
    }
    

    2- Wrap your main application with a ChangeNotifierProvider to make all declared stated in GlobalStates accessible in the whole app’s widget tree:

    void main() {
      runApp(
        ChangeNotifierProvider(
          create: (context) => GlobalStates(),
          child: MyApp(),
        ),
      );
    }
    

    3- Consume the ChangeNotifier (using Provider.of):

    class MyWidgetS extends StatelessWidget {
      // ...
    
      final globalStates = Provider.of<GlobalStates>(context);
    
      @override
      Widget build(BuildContext context) {
        // Somewhere
        globalStates.loadPrivacyPolicyAcceptance();
        globalStates.loadPrivacyPolicyAcceptance();
      }
    }
    

    The topic might be a bit broad to be fully covered, however, this should introduce how it can be achieved in its simplest forms. There are several approaches to deal with the state management.

    Also, take a look at:

    Login or Signup to reply.
  2. You can pass setState to your function and use it how you are now:

    Future<void> _loadPrivacyPolicyAcceptance(StateSetter setState) async {
        final prefs = await SharedPreferences.getInstance();
        setState(() {
          _acceptedPrivacyPolicy = prefs.getBool('acceptedPrivacyPolicy') ?? false;
        });
      }
    

    If you take this approach, you’d need to remove the underscore so the function can be called from another file.

    You can reference the official StatefulBuilder widget for inspiration.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search