Why Is My Original List Changing? A Dart Concept Every Flutter Developer Should Know
I thought I copied my list. Dart had a different idea.
You change one list. Somehow, another list changes too. You check your code. Everything looks fine.
So why is the original list changing?
Have you ever written this in Dart?
List<int> numbers = [1, 2];
List<int> secondList = numbers;Then:
secondList.add(3);And suddenly:
print(numbers);gives you:
[1, 2, 3]Wait… what? 😐
“I only changed secondList!"
I’ve been there. The problem isn’t Flutter. It’s one of those Dart fundamentals that’s easy to overlook: references and objects.
We Didn’t Actually Copy the List
When we write:
List<int> numbers = [1, 2];List<int> secondList = numbers;Dart doesn’t create a second List.
Both variables refer to the same List object:
numbers ───────┐
▼
[1, 2]
▲
secondList ───┘There is only one List. We simply have two references to it.
So when we do:
secondList.add(3);we’re modifying that one List.
That’s why both print:
[1, 2, 3]
[1, 2, 3]One small terminology clarification: secondList = numbers isn't technically a shallow copy. It's reference assignment—another reference to the same object.
And this isn’t limited to add():
secondList.remove(1);
secondList.sort();
secondList.clear();All of these modify the same List.
This Gets More Interesting in Flutter
Imagine you’re working with a list of products:
final products = getProducts();
final filteredProducts = products;Later, you want to sort the filtered list:
filteredProducts.sort(
(a, b) => a.price.compareTo(b.price),
);You think:
“I’m sorting my filtered list.”
But you’ve actually sorted products too.
Now another screen shows the products in a different order, your state looks strange, and you start wondering what Flutter did wrong. 😅
The problem was simply this:
final filteredProducts = products;You didn’t create a new List.
So How Do We Actually Copy It?
If you need a separate List, create one:
final secondList = List<int>.from(numbers);Or:
final secondList = [...numbers];Now there are two different List objects:
numbers ───► [1, 2]
secondList ───► [1, 2]So:
secondList.add(3);results in:
numbers → [1, 2]
secondList → [1, 2, 3]This is a shallow copy.
Get Apoorva Karwa’s stories in your inbox
Join Medium for free to get updates from this writer.
And here’s the part that’s easy to miss.
Shallow Copy ≠ Deep Copy
Consider a List of objects:
class User {
String name;
User(this.name);
}
final users = [
User("John"),
User("Alex"),
];
final copiedUsers = List<User>.from(users);We now have two different Lists, but the User objects inside them are still shared.
So:
copiedUsers[0].name = "Mike";also affects:
print(users[0].name);which prints:
MikeWhy?
Because List.from() created a new List, but it didn't create new User objects.
That’s what a shallow copy means:
New outer collection, but the objects inside it may still be shared.
A deep copy goes further and creates new nested objects:
final copiedUsers = users
.map((user) => User(user.name))
.toList();Now the User objects are different as well.
The same idea applies to Maps:
final user = {
"name": "John",
"age": 25,
};
final anotherUser = user;Both references point to the same Map.
To create a new outer Map:
final anotherUser = Map<String, dynamic>.from(user);But just like with Lists, nested objects can still be shared.
The Mental Model I Keep in My Head
I find it easier to remember three cases:
final b = a;Reference assignment → Same object.
final b = List.from(a);
final b = [...a];Shallow copy → New List, but nested object references may be shared.
Deep copy → New List and new nested objects.
That’s it.
This small distinction matters a lot in Flutter because we’re constantly filtering, sorting, transforming, caching, and passing Lists around in state management and UI code.
A line like:
final newList = oldList;can look completely harmless and still cause a bug that’s painful to track down.
One Last Thing
The next time you write:
final newList = oldList;don’t automatically think:
“I copied the List.”
Ask yourself:
“Did I create a new List, or did I just create another reference to the same object?”
And if you use List.from() or [...oldList], ask one more question:
“Is a shallow copy enough, or do I need the objects inside it to be copied too?”
Once you understand that distinction, this stops feeling like a mysterious Flutter bug. It’s just Dart doing exactly what you told it to do.
And yes…
I’ve been there too. 😄
Have you ever been bitten by this in Flutter? What was the weirdest symptom?
Drop it in the comments. I’d love to know I’m not the only one who’s stared at a List and thought:
“But… I didn’t change that one.” 😂





