goldenotaste
goldenotaste

Reputation: 355

Flutter - Update child state from parent

I would like to update a child's state when a button is clicked in the parent, so for example:

class Parent extends StatelessWidget{
    Widget build(context){
    return Scaffold(
            appBar: AppBar(
                actions: <Widget>[
                    IconButton(
                            onPressed: () => //somehow increment the child's counter,
                            icon: const Icon(Icons.add),
                        ),
                    
                ],
            ),
            body: const Child(),
        );
    }
}

class Child extends StatefulWidget {
    const Child({Key? key}) : super(key: key);

    @override
    _ChildState createState() => _ChildState();
}

class _ChildState extends State<Child> {
...
   int counter = 0; //to be incremented when parent's button is clicked on.
...
}

Is there a common way to implement this? From the other posts I've read, people usually use the child to update the parent's state via callback, so if there is a way to refactor my code to acheive the same effect, that would help too.

Upvotes: 4

Views: 12343

Answers (3)

lava
lava

Reputation: 7451

enter image description here

statemanagement Method

  1. You can use provider,bloc,cubit,getx... package to update the child and parent value
  2. setstate callback (here i mention)

Change you widget like this .your parent widget to stateful.

int counter = 0;
class Parent extends StatefulWidget {
  @override
  State<Parent> createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  Widget build(context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            onPressed: () {
              setState(() {
                counter++;
              });
            },
            icon: const Icon(Icons.add),
          ),
        ],
      ),
      body:  Child(),
    );
  }
}



class Child extends StatefulWidget {
   Child({Key? key}) : super(key: key);

  @override
  _ChildState createState() => _ChildState();
}

class _ChildState extends State<Child> {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text("$counter",style: TextStyle(fontSize: 30),));
  } //to be incremented when parent's button is clicked on.

SampleCod Dartpad live code check here

import 'package:flutter/material.dart';


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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Parent(),
    );
  }
}

class Parent extends StatefulWidget {
  @override
  State<Parent> createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  Widget build(context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            onPressed: () {
              setState(() {
                counter++;
              });
            },
            icon: const Icon(Icons.add),
          ),
        ],
      ),
      body:  Child(),
    );
  }
}

int counter = 0;

class Child extends StatefulWidget {
   Child({Key? key}) : super(key: key);

  @override
  _ChildState createState() => _ChildState();
}

class _ChildState extends State<Child> {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text("$counter",style: TextStyle(fontSize: 30),));
  } //to be incremented when parent's button is clicked on.

}

Upvotes: 0

My Car
My Car

Reputation: 4566

Try this:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Parent(),
    );
  }
}

class Parent extends StatefulWidget {
  const Parent({Key? key}) : super(key: key);

  @override
  State<Parent> createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  int counter = 0;

  void incrementCounter() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            tooltip: "Increment counter",
            onPressed: incrementCounter,
            icon: const Icon(
              Icons.add,
            ),
          ),
        ],
      ),
      body: Child(
        counter: counter,
      ),
    );
  }
}

class Child extends StatefulWidget {
  const Child({
    Key? key,
    required this.counter,
  }) : super(key: key);

  final int counter;

  @override
  _ChildState createState() => _ChildState();
}

class _ChildState extends State<Child> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        widget.counter.toString(),
        style: const TextStyle(
          fontSize: 30,
        ),
      ),
    );
  }
}

Upvotes: 0

Meet Prajapati
Meet Prajapati

Reputation: 501

You can create the field counter in the parent and pass it down to the child widget and update the child widget from the parent.

You can check the demo that I made here.. DartPad Demo Link

Upvotes: 6

Related Questions