There quote is from Riverpod documentation:
A StatefulWidget that can use Hook
It's usage is very similar to StatefulWidget, but use hooks inside
State.build.
The difference is that it can use Hook, which allows HookWidget to
store mutable data without implementing a State.
besides this, I can't find any sample code or another tutorial or any description more than the quote.
in this simple HookWidget how can I implement that with StatefulHookWidget?
class MyHomePage extends HookWidget {
#override
Widget build(BuildContext context) {
final store = useMemoized(() => MyStore());
return Container();
}
}
A StatefulHookWidget is for when you need to use any of the overridable functions of a regular StatefulWidget - like didChangeDependencies, or initState, or dispose.
Generally, unless you have a really good or niche reason to use StatefulHookWidget, do prefer HookWidget.
Essentially, if we replicate your example, both Class1 and Class2 are equivalent in terms of the end product. The only difference is the verbiage needed to get there.
class Class1 extends HookWidget {
const Class1({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final store = useMemoized(() => MyStore());
return Container();
}
}
class Class2 extends StatefulHookWidget {
const Class2({Key? key}) : super(key: key);
#override
_Class2State createState() => _Class2State();
}
class _Class2State extends State<Class2> {
#override
Widget build(BuildContext context) {
final store = useMemoized(() => MyStore());
return Container();
}
}
I am on the latest version of riverpod so I am using StatefulHookConsumerWidget
Following is one way to implement StatefulHookConsumerWidget. This might give you a hint for your answer
class MyHomePage extends StatefulHookConsumerWidget {
#override
_MyHomePage State createState() => _SocietyHomeState();
}
class MyHomePage extends ConsumerState<SocietyHome> {
Widget build(BuildContext context) {
return Container();
}
}
Related
Below is the definition of a Stateful Widget and its associated state. As we can see, color has been defined in YellowBird and can be accessed in _YellowBirdState via the widget object.
My question is with respect to this, how do we decide where (Widget class or State class) to define the attributes? For example, color could have been defined in _YellowBirdState directly. For now, I am deciding this based on whether I have to access the attributes from outside. For example, considering the example below, if I need to access the attribute color from outside, then I define it in the Widget class.
class YellowBird extends StatefulWidget {
const YellowBird({ Key? key }) : super(key: key);
var color = 0xFFFFE306;
#override
State<YellowBird> createState() => _YellowBirdState();
}
class _YellowBirdState extends State<YellowBird> {
#override
Widget build(BuildContext context) {
return Container(color: Color(widget.color));
}
}
One reason to create the attributes in the widget class is to pass values from outside. In your example you could pass the color dynamically.
class YellowBird extends StatefulWidget {
Color color;
YellowBird(this.color, {Key? key}) : super(key: key);
#override
State<YellowBird> createState() => _YellowBirdState();
}
class _YellowBirdState extends State<YellowBird> {
#override
Widget build(BuildContext context) {
return Container(color: widget.color);
}
}
Now you can create your widget with different colors
YellowBird(Colors.green)
YellowBird(Colors.red)
After upgrade the linter to the new version (flutter_lints: 2.0.1) in my pubspec
the linter enables this rule:
library_private_types_in_public_api by default. I don't understand why. In my App project there are a lot of widget classes extended by StatefulWidget. The state class is always private. Example projects do it the same way. Can someone explain why this rule make sense?
Btw.: I know i can disable this rule.
I encountered the same issue, it seems that now when you generate a StatefulWidget instead of returning say _ExampleState in the createState method it now returns State<Example> which avoids returning a private type. I ended up updating all of my widgets to this approach.
so
class Example extends StatefulWidget {
const Example({Key? key}) : super(key: key);
#override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
#override
Widget build(BuildContext context) {
return Container();
}
}
can be rewritten as
class Example extends StatefulWidget {
// you can also now use a super initializer for key
// if you are using dart 2.17
const Example({super.key});
// now returning State<Example>
#override
State<Example> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
#override
Widget build(BuildContext context) {
return Container();
}
}
I'm writing a Application, where Widgets and their State need to be saved to Disk and later be restored. In order to save a StatefulWidget I need to access it's corresponding State<T> object.
Here's how I imagined the code to look like:
class Block extends StatefulWidget {
const Block({Key? key}) : super(key: key);
void saveToDisk(){
// access BlockState object
// save to disk…
}
#override
BlockState createState() => BlockState();
}
class BlockState extends State<Block> {
final String _someState = ‚Hello Stackoverflow‘;
#override
Widget build(BuildContext context) {
return const Text(‚Some Text‘);
}
}
Does anybody know how to access the BlockState object (first comment in saveToDisk())?
widget.saveToDisk();
All stateful widgets have it this way.
In Flutter, when initializing a new stateful widget, it is being initialized like this by default:
class WidgetName extends StatefulWidget {
const WidgetName({ Key? key }) : super(key: key);
#override
WidgetNameState createState() => WidgetNameState();
}
I have seen another way of initializing the statefulwidget with #override being slightly different.
class WidgetName extends StatefulWidget {
const WidgetName({ Key? key }) : super(key: key);
#override
State<WidgetName> createState() => WidgetNameState();
}
Notice in the #override method, WidgetNameState became State<WidgetName>. There is an explanation in the Flutter repo that explains it: Link, but I couldn't comprehend what it is trying to say.
What does State<WidgetName> do exactly? Does it give any advantages?
I thought it wouldn't be necessary as WidgetNameState already extends from State<WidgetName> in its class construction.
class WidgetNameState extends State<WidgetName> {
#override
Widget build(BuildContext context) {
Using the generic really let's you define an abstract Widget interface that must be used without having to define any state along with that abstract widget interface.
Let's look at using the concrete class first (WidgetNameState). This is an abstract definition, we must define the state if we do this.
abstract class FooWidget extends StatefulWidget {
const FooWidget({Key? key}) : super(key: key);
#override
_FooWidgetState createState();
}
abstract class _FooWidgetState extends State<FooWidget> {
#override
Widget build(BuildContext context) {
return Container();
}
}
Now to be able to extend this you must extend both the widget and the state.
class ImplementedFooWidget extends FooWidget {
const ImplementedFooWidget({Key? key}) : super(key: key);
#override
_ImplementedFooWidgetState createState() => _ImplementedFooWidgetState();
}
class _ImplementedFooWidgetState extends _FooWidgetState {
#override
Widget build(BuildContext context) {
return Container();
}
}
Now let's look at using the generic (State<WidgetName>). If we use the generic, we can just define and extend the widget and have our own custom state.
abstract class BarWidget extends StatefulWidget {
const BarWidget({Key? key, required this.someRequiredString})
: super(key: key);
final String someRequiredString;
#override
State<BarWidget> createState();
}
class ImplementedBarWidget extends BarWidget {
const ImplementedBarWidget({Key? key, required String someRequiredString})
: super(
key: key,
someRequiredString: someRequiredString,
);
#override
_ImplementedBarWidgetState createState() => _ImplementedBarWidgetState();
}
class _ImplementedBarWidgetState extends State<ImplementedBarWidget> {
#override
Widget build(BuildContext context) {
return Container();
}
}
I hope that all makes sense.
I have a stateful widget that has one method called in initialisation. I wanna know how to be able to get a parameter from the previous screen and pass it in initState to my initialisation method
class LabDetalheWidget extends StatefulWidget {
final String path;
const LabDetalheWidget({
Key key,
this.path,
}) : super(key: key);
You can pass parameter like that
class MyWidget extends StatefulWidget {
final String param;
const MyWidget({
Key key,
this.param,
}) : super(key: key);
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
#override
void initState() {
print(widget.param);
super.initState();
}
#override
Widget build(BuildContext context) {
return Container(
);
}
}
Inside the state you can access the parameter like that
print(widget.param)
I believe you wanna pass data across routes.. If so then read this flutter cookbook's section you might get the idea
https://flutter.dev/docs/cookbook/navigation/passing-data