Labs ICT
Pro Login

setState and Local State

Managing state within a widget.

setState() to Update StatefulWidgets

setState is how you tell Flutter that the state of your widget has changed and the UI needs to rebuild. You call it inside a StatefulWidget's State class, and whatever you put inside the setState block updates the widget. Without setState, changes to your variables won't be reflected on screen.

class CounterPage extends StatefulWidget {
  @override
  _CounterPageState createState() => _CounterPageState();
}

class _CounterPageState extends State {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Counter')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: $count', style: TextStyle(fontSize: 32)),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  count++;
                });
              },
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}
Try it Yourself ->

Toggle Pattern

Toggling a boolean is one of the most common state patterns. Think show/hide password, light/dark mode switch, or expanding/collapsing an accordion. Just flip the boolean inside setState and the UI updates immediately.

class PasswordField extends StatefulWidget {
  @override
  _PasswordFieldState createState() => _PasswordFieldState();
}

class _PasswordFieldState extends State {
  bool obscure = true;

  @override
  Widget build(BuildContext context) {
    return TextField(
      obscureText: obscure,
      decoration: InputDecoration(
        labelText: 'Password',
        suffixIcon: IconButton(
          icon: Icon(obscure ? Icons.visibility : Icons.visibility_off),
          onPressed: () {
            setState(() {
              obscure = !obscure;
            });
          },
        ),
      ),
    );
  }
}
Try it Yourself ->

Form Input Pattern

When handling form inputs, setState keeps the UI in sync with what the user types. You store the input value in state, and update it whenever the onChanged callback fires. This pattern works for text fields, dropdowns, checkboxes, and more.

class NameForm extends StatefulWidget {
  @override
  _NameFormState createState() => _NameFormState();
}

class _NameFormState extends State {
  String name = '';
  String greeting = '';

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(16.0),
      child: Column(
        children: [
          TextField(
            decoration: InputDecoration(labelText: 'Enter your name'),
            onChanged: (value) {
              setState(() {
                name = value;
              });
            },
          ),
          SizedBox(height: 16),
          ElevatedButton(
            onPressed: name.isEmpty ? null : () {
              setState(() {
                greeting = 'Hello, $name!';
              });
            },
            child: Text('Greet'),
          ),
          SizedBox(height: 16),
          Text(greeting, style: TextStyle(fontSize: 20)),
        ],
      ),
    );
  }
}
Try it Yourself ->