In Flutter, you can have either a Statefulwidget or a StatelessWidget. Think of State as the data, state, position of the widget within the widget tree.

if you think your widget will change it's state, through the user interaction then that widget needs to be stateful. In practice we want to make as few stateful widgets as possible and have a state management tool such as provider but that is more advanced than what we know so far.

but for now we should know that stateful widgets are more flexible and we can change their state, for example I have a widget called MyApp

 

MyApp --- Stateless widget

MyApp then has a build method that renders a question with three buttons.

I want to be able to change the question and move on to the next question every time a button is pressed, this means the "state" of MyApp will change every time the button is pressed and it might be a good idea to use Stateful widget instead.

keep in mind that a typical page in your app will have many widgets, you only need to have stateful widgets for the parts that will change based on the user interaction.

 

let's jump into the code:

MyApp extends StatefulWidget making the widget Stateful and allowing us to use the state functionality.

MyApp now needs a second class with extends State class that has a type of MyApp, this makes sure the App State is linked to MyApp and finally we pass this object to the createState() method of a stateful widget.

 

the code part of your widget's code will go into the _MyAppState and you will manage the state from there too.

void main() => runApp(MyApp());

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

class _MyAppState extends State<MyApp> {
  var questionIndex = 0;

  void answerQuestion() {
    
    setState((){
        questionIndex = questionIndex ==1 ?0: questionIndex+1;
        print(questionIndex);
    });  
  }

  @override
  Widget build(BuildContext context) {

 

Also, note the function I have for answerQuestion(), this function is passed on to the onPressed arguments of the raised buttons as you will see below.

answerQuestion() does two things:

1. It will increase the questionIndex which is a variable.

2. And more importantly it will use setState(), setState is used to change what's rendered on the screen when a change happens, so every time something changes in your app, you want to call setState() to take care of the changes, setState() recalls the build method of the widget you are using it in, in this example, the questionindex has changed and as you will see below, question index is responsible for showing the question at this index on to the screen.

so the question on the screen will change, therefore the state of the widget will change!

 

 

setState takes in a function as an argument.

setState(() {});

you write your logic inside the second function as show below:

    setState((){
        questionIndex = questionIndex ==1 ?0: questionIndex+1;
        print(questionIndex);
    });

 

here is the full code:

 

 

import 'package:flutter/material.dart';

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

void main() => runApp(MyApp());

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

class _MyAppState extends State<MyApp> {
  var questionIndex = 0;

  void answerQuestion() {
    
    setState((){
        questionIndex = questionIndex ==1 ?0: questionIndex+1;
        print(questionIndex);
    });  
  }

  @override
  Widget build(BuildContext context) {
    var questions = ["What's your name?", "What's your favorite color?"];


    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('My Title'),
        ),
        body: Column(
          children: [
            Text(questions.elementAt(questionIndex)),
            RaisedButton(
              child: Text('Answer 1'),
              onPressed:  answerQuestion,
            ),
            RaisedButton(
              child: Text('Answer 2'),
              onPressed: answerQuestion,
            ),
            RaisedButton(
              child: Text('Answer 3'),
              onPressed: answerQuestion,
            ),
          ],
        ),
      ),
    );
  }
}

 

setState() is a "trigger" that informs Flutter that it needs to re-run build() of the Widget.