How to Send Data From Child Widget to its parent In Flutter

How to Send Data From Child Widget to its parent In Flutter?

Consider a case where the user is having a widget tree in which the status of a child widget decides the status of a parent widget. So in this article, we will go through how to Send Data From Child Widget to its parent in flutter. Know all details about how flutter pass data from child to parent. Let’s learn how to efficiently send data from a child widget to its parent in Flutter, a fundamental technique in mobile app development for startups.

How to Send Data From Child Widget to its parent In Flutter?

The first possibility is to pass a callback into your child, and the second is to use the pattern for your stateful widget. See below.

import 'package:flutter/material.dart';

class MyStatefulWidget extends StatefulWidget {
  @override
  State createState() => MyStatefulWidgetState();
}

class MyStatefulWidgetState extends State {
  String _string = "Not set yet";

  void updateString(String value) => setState(() => _string = value);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(_string),
        MyChildClass(callback: updateString), // Pass updateString function
      ],
    );
  }
}

class MyChildClass extends StatelessWidget {
  final Function(String) callback; // Use a more generic function type

  MyChildClass({required this.callback}); // Make callback required

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextButton( // Replace FlatButton with TextButton
          onPressed: () => callback("String from method 1"),
          child: Text("Method 1"),
        ),
        TextButton( // Replace FlatButton with TextButton
          onPressed: () => callback("String from method 2"),
          child: Text("Method 2"),
        ),
      ],
    );
  }
}

void main() => runApp(
  MaterialApp(
    home: MyStatefulWidget(),
  ),
);

There is also the alternative of using an Inherited Widget instead of a Stateful Widget this is particularly useful if you want your child widgets to rebuild if the parent widget’s data changes and the parent isn’t a direct parent.

import 'package:flutter/material.dart';

class MyStatefulWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new MyStatefulWidgetState();

  // --> NOTE this! <--
  static MyStatefulWidgetState of(BuildContext context) =>
    context.findAncestorStateOfType<MyStatefulWidgetState>();
}

class MyStatefulWidgetState extends State<MyStatefulWidget> {
  String _string = "Not set yet";

  set string(String value) => setState(() => _string = value);

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new Text(_string),
        new MyChildClass(callback: (val) => setState(() => _string = val))
      ],
    );
  }
}

typedef void StringCallback(String val);

class MyChildClass extends StatelessWidget {
  final StringCallback callback;

  MyChildClass({this.callback});

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new FlatButton(
          onPressed: () {
            callback("String from method 1");
          },
          child: new Text("Method 1"),
        ),
        new FlatButton(
          onPressed: () {
            MyStatefulWidget.of(context).string = "String from method 2";
          },
          child: new Text("Method 2"),
        )
      ],
    );
  }
}

void main() => runApp(
      new MaterialApp(
        builder: (context, child) => new SafeArea(child: new Material(color: Colors.white, child: child)),
        home: new MyStatefulWidget(),
      ),
    );

Generally, you use Navigator.pop(context, “your data here”); but you can also pass the data in this manner.

class ParentScreen extends StatefulWidget {
  @override
  _ParentScreenState createState() => _ParentScreenState();
}

class _ParentScreenState extends State<ParentScreen> {
  String _text = "";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Parent screen")),
      body: Column(
        children: <Widget>[
          RaisedButton(
            child: Text("GO TO CHILD"),
            onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => ChildScreen(func: function))),
          ),
          Text(_text),
        ],
      ),
    );
  }

  function(value) => setState(() => _text = value);
}

class ChildScreen extends StatelessWidget {
  final Function func;

  const ChildScreen({Key key, this.func}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Child screen")),
      body: RaisedButton(
        child: Text("BACK TO PARENT"),
        onPressed: () {
          func("This is the data which child has passed"); // passing data to parent
          Navigator.pop(context);
        },
      ),
    );
  }
}

The above code will give us output like a below:

stateful widget-Send Data From Child Widget to its parent In Flutter
stateful widget-Send Data From Child Widget to its parent In Flutter

Use InheritedWidget – https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html

This lets you access data of the parent in all the children

I think notifications are quite a civilized solution and they allow for very clean communication without variable juggling and they bubble up if you need them to:

Define a notification:

class SwitchChanged extends Notification {
  final bool val
  SwitchChanged(this.val);
}

Raise notification in your child’s event handler:

onPressed: () {
  SwitchChanged(true).dispatch(context);
}

Finally, wrap your parent with notification listener:

NotificationListener<ItemChangedNotification>(
  child: YourParent(...),
  onNotification: (n) {
    setState(() {
      // Trigger action on parent via setState or do whatever you like.
    });
    return true;
  }
)

Conclusion:

Thanks for being with us on a Flutter Journey!!!

So in this article, we have been through how to Send Data From Child Widget to its parent in flutter.

Keep Learning !!! Keep Fluttering !!!

Nirali Patel

Written by Nirali Patel

Nirali Patel is a dedicated Flutter developer with over two years of experience, specializing in creating seamless mobile applications using Dart. With a passion for crafting user-centric solutions, Nirali combines technical proficiency with innovative thinking to push the boundaries of mobile app development.

Leave a comment

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

Discuss Your Project

Connect with Flutter Agency's proficient skilled team for your app development projects across different technologies. We'd love to hear from you! Fill out the form below to discuss your project.

Have Project For Us

Get in Touch

"*" indicates required fields

ready to get started?

Fill out the form below and we will be in touch soon!

"*" indicates required fields