Comments (2)
ReSwift is an awesome framework, I used it years ago and it was really nice. Probably you'll find a lot of articles speaking about it and other frameworks extending it, so it's what I really recommend in case you're new to redux pattern and needs something more consolidated.
However some things I wanted to make different, and now, after years working on SwiftRex and having new ideas from different sources (including ideas posted as Github issues, as you can check in the history), I believe it's getting very close to what I see as "1.0", except that docs are still outdated in some parts. I think we now have a very different implementation from ReSwift and Zendesk Suas, my main sources of inspiration when I started SwiftRex.
I'll try to list some of the differences here:
- ReSwift uses a protocol
Action
which has to be implemented by your actions in order to be understood by the store. SwiftRex no longer uses such protocol, instead ActionType is generic type of the store and this is not a small difference. EVERYTHING in SwiftRex are built on top of generics parameters, making it much more type-safe, and although it makes it a bit harder to use - Swift generics are hard - more things happening in compile time protect you from runtime errors. - Because we rely on generics for actions and state, we can have subset of actions and subset of state, derived from the global one, and with that also derive Store, Middleware and Reducer. That means you can have a "sub-Store" which is not the store itself, only a projection of the global store to handle specific problems. Your UIViewController/SwiftUI View will no longer see the whole state, only what you choose to share. This also allows you to put views in different Swift modules and bring only the actions and state that are relevant to that view, not the whole thing.
- Same for Middlewares and Reducers, you can have a "CoreLocationMiddleware" that will understand a state that is only "CLLocationCoordinate2D" and an action like "newLocation". You make it a Swift Package and use in any app you want, for that all you have to do is to add somewhere in your global state a property
var currentLocation: CLLocationCoordinate2D
and, when you plug that middleware, you pass the keypath to this property, "teaching" how to resolve the local state from the global state. - We think that Actions should be a enum tree, so you can resolve the sub-action from global action as well, that will enforce you to handle all the cases and compile will warn you if you add a new action and forget to handle it.
- ReSwift has its own "reactive framework" inside of it. The subscriptions are handled by the Store and with that all the concurrency problems that are, in my opinion, better handled by RxSwift, ReactiveSwift and Combine. That's why SwiftRex doesn't implement this layer, instead we have an abstraction on top of Subscriptions, Publishers, Subscribers and Subjects, but those don't really implement any logic, they are type-erased versions of RxSwift, ReactiveSwift and Combine components. This technique is often called protocol witness (https://www.pointfree.co/episodes/ep33-protocol-witnesses-part-1).
- There are frameworks integrating ReSwift with RxSwift, but it's not part of the core framework and I'm not sure if they release versions together to ensure compatibility, and in the end the integration happens outside of the Store, so the subscriptions will still be handled by the store.
- You can derive your store multiple times, having a projection from another projection. This is very useful in some architectures, for example if you use MVP or MVVM, your VM can be a store projection which converts view events (button tap) into actions (userLogin) and state (valid password) into view state (button disabled). And you derive all these things using generic parameters, you can confidently and exhaustively switch over enums)
- This is also useful for SwiftUI, because
ObservableViewModel
holds a projection of your store and it's the@ObservedObject
expected by your View.
There are probably more differences but these are the main ones.
ReSwift is a very solid project, maintained by more than 50 contributors and with more than 6 thousand stars. It's the natural choice if you are new to this architecture and need more support from community and articles. On the other hand, SwiftRex has heavily used functional programming techniques to ensure a more safe runtime. I'm working to improve the docs and offer more tooling (integration with Redux DevTools for example https://github.com/reduxjs/redux-devtools), more complex examples and more middlewares. However, so far it's a single-person-project and I can't always go as fast as want. But I've been using it in multiple projects for the last years and it's very stable, testable and consistent. And I'm doing my best to listen the suggestions, fix bugs and help with people new to redux, regardless if they are planning to use SwiftRex or any other framework.
from swiftrex.
Just to be clear, when you derive a sub-Store you're not creating a second store. In "Flux" architecture you have multiple stores and must keep them in sync. Here, you have one and only one store, the same way that is suggested by ReSwift.
Deriving a store means you have something that behaves like a store (implements the same protocol), but not for the whole state only partial state (and action). But in the end, this projection doesn't actually stores anything, only redirects actions and state to the real store, running the "lift" function whenever it needs to "convert" globals into locals and vice-versa.
Before it was called ViewStore, but because it's not a store (it has no storage), the new name is StoreProjection. I like that much more :) But naming things is hard.
from swiftrex.
Related Issues (20)
- middleware lift with WritableKeyPath doesn't work on AnyMiddleware HOT 2
- Fix animations from Middleware
- Dead-Letter Queue HOT 1
- Memory leak in LiftMiddleware
- When will develop be the official release? HOT 2
- Lift EffectMiddleware using KeyPath not receiving context
- How to modify AppLifecycleMiddleware to adopt the new MiddlewareProtocol? HOT 2
- Redundant conformance of 'ASAPScheduler' to protocol 'Scheduler'
- Using await/async in middleware HOT 4
- IO monad and stack limit HOT 6
- I think it's time to enable Enabling Concurrency warnings in Xcode HOT 2
- Dynamic store HOT 5
- Migrate away from Travis CI HOT 4
- Design question : Model to State migration HOT 2
- Dispatch actions and run reducers on background thread? HOT 4
- CombineRex : Unexpected PublisherType behavior HOT 3
- Trying to use Effect.promise with Firebase's DynamicLinkComponents.shortenURL HOT 5
- Question about assertionFailure() HOT 5
- How organize communication between different states HOT 2
- Improve Tests
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from swiftrex.