Shared State Not Using Injected Dependencies When Created in SwiftUI View #3132
-
I think I've found a rough edge with the shard state functionality that I'm not totally sure how to work around. In essence, if I'm creating some shared state as part of a I've attached a sample project that reproduces the issue. It's a simple document editor that keeps an index of the documents. It's set up so that the index exists as one file, and then each document is its own file named by the identifier of the document. When I create my root store, I override the default file system to be the in memory implementation, to showcase this issue. Then, when I display a list of documents, I create the editor state for that specific document, which sets up a shared state to read the specific document's file. Because this happens in the view and not in the reducer, this used the default live implementation of the file system, which actually writes out the file to disk, instead of using the in memory implementation. Feel free to run this app, create a document, and then edit it. If you run Now, this all makes sense. The SwiftUI view is separate from the reducer, so they're not sharing dependencies. This is how swift-dependencies is supposed to work. I'm just not entirely sure how to get it to work how I want it to work, to get the shared state to use the injected dependency. I've thought of a couple of different ways to try to resolve this, but they all seem to have various problems.
So I'm not fully sure how to proceed here. I can definitely do option 1 to unblock myself for now, but it'd be nice if there was a potential solution here that didn't require me to do that, and I'm just "holding it wrong" and there is a way to get this to do what I want. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Hi @grantjbutler, I believe I understand the problem you are describing, but I must apologize I did not read your entire post in depth. I believe I have a suggestion for you, but it may have been something you already considered. My suggestion is to not use So I would suggest to just use a Roughly, something like this: case let .path(.element(id: _, action: .child(.rowTapped(id)))):
guard let sharedDoc = state.documentsList.$documents[id: id]
else { return .none }
state.path.append(
.anotherChild(
AnotherChild.State(document: sharedDoc)
)
) |
Beta Was this translation helpful? Give feedback.
Hi @grantjbutler, I believe I understand the problem you are describing, but I must apologize I did not read your entire post in depth. I believe I have a suggestion for you, but it may have been something you already considered.
My suggestion is to not use
NavigationLink(state:)
. It's a great tool to have in a pinch, but also at the same time it's pretty problematic. Not only for the reasons you are seeing here, which is state created in the view can lose its dependencies, but also it strongly couples all the features in the stack together.So I would suggest to just use a
Button
, send an action that the parent intercepts, and then construct the child state in the parent reducer. Then al…