pointfreeco/swift-composable-architecture

ForEach<_StoreCollection<String, State, Action>, ObjectIdentifier, SingleTaskView>: the ID ObjectIdentifier(0x0000600003fe8b40) occurs multiple times within the collection, this will give undefined results!

Closed this issue · 2 comments

Description

I have studied the latest code of ToDos and tried to improve my project. But the unexpected issue occured. I am not sure if I did something wrong.
I replace Array<Task> with IdentifiedArrayOf<Task> and replace

ForEachStore(
  store.scope(
    state: \.tasks,
    action: \.tasks
  )
) { (store) in
   SingleTaskView(store: store)
}

with

List {
      ForEach(store.scope(state: \.tasks, action: \.tasks)) { store in
        SingleTaskView(store: store)
      }
} 

Then the issue occured.

Checklist

  • I have determined whether this bug is also reproducible in a vanilla SwiftUI project.
  • If possible, I've reproduced the issue using the main branch of this package.
  • This issue hasn't been addressed in an existing GitHub issue or discussion.

Expected behavior

Can someone help me, Thanks

Actual behavior

ForEach<_StoreCollection<String, State, Action>, ObjectIdentifier, SingleTaskView>: the ID ObjectIdentifier(0x0000600003fe8b40) occurs multiple times within the collection, this will give undefined results!

Steps to reproduce

I tried to reassgin the value of state.todos.

The Composable Architecture version information

1.10.0

Destination operating system

macos 14.3

Xcode version information

Version 15.2 (15C500b)

Swift Compiler version information

Swift version 5.9.2

I logged state.todos and there were no identical ids.

@zhangpeibj01 In the upgrade guide we note that the 1:1 migration requires you to explicitly select the id from store state, otherwise ForEach will take the child store's object identifier:

https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/migratingto1.7#Replacing-ForEachStore-with-ForEach

So you should update your code for a true comparison:

 ForEach(
-  store.scope(state: \.tasks, action: \.tasks)
+  store.scope(state: \.tasks, action: \.tasks), id: \.state.id
 ) { store in
   SingleTaskView(store: store)
 }

I'm going to convert this to a discussion since it doesn't appear to be a bug with the library, but if you do think you've encountered a bug, please provide a sample project that reproduces the issue. Without it we won't be able to troubleshoot the problem.