Can I pass any data with SetRouteAction?
With ReSwift StandardAction I can pass some arbitrary payload. Looks like I can't do it with the help of SetRouteAction, because it only takes an array of RouteElementIdentifiers which are, unfortunately, strings.
I think there's an opportunity for major overhaul, because routes for parametrized controllers are effectually impossible. Also string route identifiers stink.
I tried creating an extension called RoutableEnumerable which lets you SetRouteAction([SomeEnum.someCase]). Thanks to Swift enums we can have associated values which would allow you to pass data via SetRouteAction. The problem is with stacking enums of different types:
SetRouteAction([Enum1.route1, Enum2.someOtherRoute(someAssociatedData)])
It throws a compiler error that says the SetRouteAction cannot be initialized with an array of type [Any]. There is the potential to create a common protocol that your enums conform to, but I couldn't figure it out in a time crunch.
Also, there is the problem of serializing your associated values into RouteElementIdentifier (String), so some core code would need to be changed for this to work, but I made a workaround (https://github.com/JamesPerlman/StringParser) so you can serialize/deserialize enums with associated values into RouteElementIdentifiers. The result was very ugly as swift does not have the reflection capabilities to do this automatically or gracefully, so the code was verbose.
My peer pointed out that we could simply store all routable states in a single enum to avoid the typecasting issue (a common protocol for each enum didn't help either) - but our app is enormous, and having all routable states in a single enum would mean we could only have one gigantic inflated Routable.
Another developer peer of mine got it to work with RoutableEnumerable, but...
Long story short, I believe this is an abuse of Redux. Personally, I believe you should set your state in one ViewController (or whatever class/entity), then dispatch your SetRouteAction, and read the state from the target entity/class/viewcontroller you wish to "pass" data to. AKA the data you wish to "pass" should be stored somewhere down the chain of states in your Store.
Check out the example project. They use this pattern when using Bookmarks.
Hope that helps.
Parameters to support nested detail views, for example?
/user/Foo/photos/12345/user/Bar
Foo profile
Her pirctures with ID 12345
Bar user profile (linked from picture)
That should be doable, but passing the 2 user type references and the photo item with the state, not so much. Is it the latter you want to achieve?
@JamesPerlman I find the idea of setting state and then pushing a route and then reading from the state in the next 'component' in keeping with the 'keep everything in the store' philosophy. But I think it might be problematic. If you put it in NavigationState, technically its still in the store. But you are keeping a clean separating of 'domain state' and 'ui state'.
One thing I've noticed people do on the web is to pass transient navigation data into react props. Usually a component will be created with as little data as possible, e.g. a (pseudo react code) <Todo id={route.data}> and now that component can bind to the 'domain state' of the store. My feeling is that this prevents the state shape from becoming too coupled on the navigation state.
To that end I've been using a stringly typed schema e.g. ["todos", "todo:{42}"] for passing navigation data to build up a 'nav tree'. The data is associated with the current navigation state (through the navigationState) and not muddied together with the domain state.