0

Imagine I have the following situation:

We have a stateful widget A, which stores some map. Widget A passes this map to stateful widget B, which stores it as a local variable in initState. Then, any changes in this local map (within widget B) somehow affect the original map (the one in widget A).

How is it possible?

Some basic code for illustation:

class A extends StatefulWidget {
  @override
  _AState createState() => _AState();
}

class _AState extends State<A> {
  Map _someMap = {
    'key': 'Some value',
    'anotherKey': 'Some another value',
  };

  @override
  Widget build(BuildContext context) {
    return B(
      inheritedMap: _someMap,
    );
  }
}

class B extends StatefulWidget {
  final Map inheritedMap;

  B({this.inheritedMap});

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

class _BState extends State<B> {
  Map _inheritedMapCopy;

  @override
  void initState() {
    _inheritedMapCopy = widget.inheritedMap;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      onChanged: (val) {
        print('Parent data before change:');
        print(widget.inheritedMap);

        _inheritedMapCopy['key'] = val;

        print('Parent data after change:');
        print(widget.inheritedMap); /// Contains all the changes for _inheritedMapCopy
      },
    );
  }
}
emvaized
  • 884
  • 12
  • 23

1 Answers1

2

The problem here is that Maps and Lists point to the data in the memory. When you pass your Map to B, its reference in memory is still the same so the same data is being manipulated. What you can do to safely copy the contents is use the .from() constructor like this-

_inheritedMapCopy = Map.from(widget.inheritedMap);

Note that this will perform a shallow copy and not a deep one (for cases when the contents of the Map also include Maps or Lists). Read more about them here

AshishB
  • 747
  • 7
  • 18