How do you use the setState() function as part of a Flutter widget?

Issue

Here’s a Dart Stack that I’d like to be able to reuse:

Stack(children: [
  Align(
    alignment: Alignment.centerLeft,
    child: IconButton(
        splashRadius: 20,
        icon: const Icon(Icons.keyboard_arrow_down_rounded),
        tooltip: 'decrease bonus by 1',
        onPressed: () => setState(() => value -= 1)),
  ),
  Container(
      width: 90,
      child: Center(child: Text(value.toString()))),
  Align(
    alignment: Alignment.centerRight,
    child: IconButton(
        splashRadius: 20,
        icon: const Icon(Icons.keyboard_arrow_up_rounded),
        tooltip: 'increase bonus by 1',
        onPressed: () => setState(() => value += 1)),
  ),
])

Ideally, I’d like to turn this stack into a widget or function that I could call with a Widget like ArrowIncrement(value: value) or a function like ArrowIncrement(value), but I can’t get it to work due to the error the function 'setState' isn't defined.

Is there a solution or workaround for this issue?

Solution

You can wrap it into your own widget:

class MyWidget extends StatelessWidget {
  final ValueChanged<int> onValueChanged;
  final int value;
  
  MyWidget({required this.value, required this.onValueChanged});
  
  @override
  Widget build(BuildContext context) {
    return Stack(children: [
  Align(
    alignment: Alignment.centerLeft,
    child: IconButton(
        splashRadius: 20,
        icon: const Icon(Icons.keyboard_arrow_down_rounded),
        tooltip: 'decrease bonus by 1',
        onPressed: () => onValueChanged(value-1)),
  ),
  Container(
      width: 90,
      child: Center(child: Text(value.toString()))),
  Align(
    alignment: Alignment.centerRight,
    child: IconButton(
        splashRadius: 20,
        icon: const Icon(Icons.keyboard_arrow_up_rounded),
        tooltip: 'increase bonus by 1',
        onPressed: () => onValueChanged(value+1)),
  ),
]);
  }
}

… and then use it like this in your build method (assuming you have a variable called currentBonusValue in your state):

MyWidget(
    value: currentBonusValue, 
    onValueChanged: (newValue) => setState(() => currentBonusValue = newValue),
)

Answered By – nvoigt

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *