Search code examples
flutterstate

Call setState outside widgets


Can I call setState from outside the widgets. I try to register the setState of the children widgets - and call it from outside. It don't seem to work - why is that?

import 'package:flutter/material.dart';
import 'package:linkimager/sizes.dart';
import 'package:linkimager/store.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> {

  @override
  Widget build(BuildContext context) {
    ScreenSizes.init(MediaQuery.of(context).size);
    int number = 0;
    return MaterialApp(
      home: Scaffold(
        body: ChildWidget(number),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            number++;
            Renderer.setStateChild();
          },
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

class ChildWidget extends StatefulWidget {
  final int number;

  const ChildWidget(this.number, {super.key});

  @override
  ChildWidgetState createState() => ChildWidgetState();
}

class ChildWidgetState extends State<ChildWidget> {

  @override
  void initState() {
    print("registered setStateChild");
    Renderer.setStateChild = () => setState;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Center(child: Text(widget.number.toString()));
  }
}

class Renderer {
  static Function setStateChild = () {}; 
}

Im not looking for state management tools but want to understand what is blocking the rendering from outside


Solution

  • I made this example for you:

        import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatefulWidget {
      const MyApp({super.key});
    
      @override
      MyAppState createState() => MyAppState();
    }
    
    class MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        // ScreenSizes.init(MediaQuery.of(context).size);
        int number = 0;
        return MaterialApp(
          home: Scaffold(
            body: ChildWidget(),
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                number++;
                Renderer.setStateChild();
              },
              child: const Icon(Icons.add),
            ),
          ),
        );
      }
    }
    
    class ChildWidget extends StatefulWidget {
      const ChildWidget({super.key});
    
      @override
      ChildWidgetState createState() => ChildWidgetState();
    }
    
    class ChildWidgetState extends State<ChildWidget> {
      int number = 0;
    
      @override
      void initState() {
        print("registered setStateChild");
        Renderer.setStateChild = () {
          setState(() {
            print("setStateChild called");
            number++;
          });
        };
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Center(child: Text(number.toString()));
      }
    }
    
    class Renderer {
      static Function setStateChild = () {};
    }
    

    I hope its close to what youre looking for.