UTKARSH Sharma
UTKARSH Sharma

Reputation: 836

How am I able to pass setState in a stateless widget from a statefull widget

In the below code I have passed set state as a function call in a stateless widget how is this possible I know there is nothing wrong with flutter, but its something about the functions in general, I am not getting the basics right can someone plz explain me this concept. Comments are provided for assistance.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {    //STATEFUL WIDGET
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Demo(function: () {
            setState(() {});      //PASSING SET STATE
          });
        },
      ),
    );
  }
}

class Demo extends StatelessWidget {  //STATE  LESS WIDGET
  final Function function;
  Demo({this.function});

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

Upvotes: 2

Views: 9291

Answers (3)

raghav042
raghav042

Reputation: 904

Here's another example: we have a class contains a function which require setState and want to use that function from a stateful widget, so I can pass that function by following way.

class Api {
  static bool isLoading = false;
// want to use setState in this function

  static Future<void> getApiResponse({
    required Function(bool) function, //here I setState bool = true so I write bool
  }) async {
    // setState
    function(true);
    try {
      //TODO: some code
      // setState
      function(false);
    } catch (e) {
      //setState
      function(false);
      throw e;
    }
  }
}

// function in stateful widget
Future<void> func1() async {
  await Api.getApiResponse(
    function: (bool value) {
      setState(() {
        Api.isLoading = value;
      });
    },
  );
}

Upvotes: 0

Abion47
Abion47

Reputation: 24661

In Dart, methods and functions can be passed around just as though they were normal variables and values. In this case, you have passed the setState method from the stateful widget into the constructor of the stateless widget. (Or, more precisely, you have wrapped a call to the stateful widget's setState in an anonymous function and then passed that function to the stateless widget.)

This can be demonstrated more simply in the following way:

class A {
  int x = 0;

  void doThing() {
    x = 5;
  }
}

class B {
  Function f;

  B(this.f);

  void runFunction() {
    f();
  }
}

// ...

A a = A();
B b = B(a.doThing);
b.runFunction();
print(a.x);

// Prints: 5

In this example, the doThing from a is passed into b, which assigns it to b.f. When b calls f, it is the same as calling a.doThing directly, which can be shown by a.x having the updated value after the fact. This is what is known as passing a callback, which is a function passed to another function or object that can then be called without having to reference the passed-in function directly. i.e. b can call a.doThing by calling the callback f() without having to explicitly call a.doThing(). (Note: this is a very simplistic explanation of a callback, and a more detailed explanation goes into the nuance of how the passed function is actually used.)

This is not the same as saying that a.doThing now belongs to b, and b does not now magically have a doThing method. Likewise, when you pass in setValue to a stateless widget, you are not magically granting that widget a state and you are not breaking the rules of Flutter by suddenly being able to call "setState" from a stateless widget any more than if you had passed an instance of the State<MyApp> itself and called stateObj.setState(...) directly (not that I am recommending you do that, of course).

Upvotes: 2

Peter Haddad
Peter Haddad

Reputation: 80914

setState() is a method inside the State class. In your code you have the following:

   onPressed: () {
          Demo(function: () {
            setState(() {});      //PASSING SET STATE
          });
        },

Here you create an instance of Demo and give it a callback as an argument. Inside that callback, you are calling setState which is a method inside the State class.

Upvotes: 4

Related Questions