Reputation: 836
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
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
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
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