Comments (5)
@soapsign, you are bringing up a good point! The current protocol fairly closely resembles the Redux implementation. It has the advantage that you can initialize a Store without the need of initializing the state. In many cases you won't have all information to provide an initial state at that point in time.
The idea of the current protocol is, that a reducer owns a slice of your state and thus should know best how to initialize it.
I however agree that this assumption might not always be correct. Could you maybe share your example? That would make the discussion easier.
I could imagine that it makes sense to offer to initialization paths:
- Provide initial state and provide reducer that assumes initialized state
- Don't provide initial state and provide reducer that can hydrate
Using a separate protocol we could accomplish this. Definitely worth discussing.
Thanks for bringing this up!
from reswift.
Consider my AppState
has 2 subState which is StateA
and StateB
. Then 'AppState' needs to conform to StateType
, HasStateA
and HasStateB
. For HasStateB
, the definition is as follow
protocol HasStateB {
var stateB: StateB? { get set }
}
It is defined as StateB?
as this subState should only available for a limited of time for a small part of the application and should be cleaned after use.
Then I have a StateBReducer
, which should implement
func handleAction(action: Action, state: HasStateB?) -> HasStateB
.
There are a few problem with this requirement.
First, what should I return If I want to hydrate this subState, as HasStateB is a protocol.
Second, the Store
call my Reducer
no matter what Action
is dispatching. This makes the Reducer
to hydrate the state as soon as the first Action
is dispatched.
The possible solution for 2nd problem is allow a reducer to return Optional
, which is something like
`func handleAction(action: Action, state: HasStateB?) -> HasStateB?'.
For the 1st Problem, it seem that the only possible way is the create another Reducer
which is StateType
alias define to AppState
, so to avoid the return type is protocol problem.
Maybe I am doing this optional subState in a wrong way, but this is the problems I face when I want to achieve this optional subState.
from reswift.
struct AppState: StateType, HasStateA, HasStateB {
var stateA: State
var stateB: State?
}
struct State {
var value: String
}
protocol HasStateA {
var stateA: State { get set }
}
protocol HasStateB {
var stateB: State? { get set }
}
enum StateAAction: Action {
case ChangeValue(String)
}
enum StateBAction: Action {
case ChangeValue(String)
}
struct StateAReducer: Reducer {
func handleAction(action: Action, var state: HasStateA?) -> HasStateA {
// filtering action
guard let action = action as? StateAAction else {
return state!
}
switch action {
case .ChangeValue(let value):
state?.stateA.value = value
return state!
}
}
}
struct StateBReducer: Reducer {
func handleAction(action: Action, var state: HasStateB?) -> HasStateB {
// filtering action
guard let action = action as? StateBAction else {
return state!
}
// hydrating state if nil
var stateB = state?.stateB ?? State(value: "B")
switch action {
case .ChangeValue(let value):
stateB.value = value
state?.stateB = stateB
return state!
}
}
}
I finally manage to implement the optional sub state, turn out that the Self.ReducerStateType?
is not intended for substate but for the whole store at all.
However, I think
func handleAction(action: Action, state: Self.ReducerStateType?) -> Self.ReducerStateType
is still ambiguous and misleading, could we make it clear that some Reducer
s are not take part in hydrating the store?
And one thing I notice is that to hydrate the store with reducer need to take special care to the order of the reducers.
from reswift.
@soapsign Thanks a lot for all the details! Yes, a part of the reducer API is a little bit confusing, since it is currently a mix of the original Swift Flow way of handling reducers and the ReduxKit way. I actually prefer many aspects of the ReduxKit approach, because it makes handling substates easier.
I don't have time for a fill write-up now, but I will get back to this 😃
Thanks a lot for the input!
from reswift.
After switching into the solution @Ben-G suggested in #90, the problem solved cleanly.
from reswift.
Related Issues (20)
- Concurrency - protected reads HOT 2
- How to subscribe/unsubscribe store in a UIView like in UITableViewCell, CollectionViewCell etc ? HOT 1
- What's a good way to cast results of a subscription in SwiftUI to a desired output type? HOT 3
- Managing ReSwift app state inside FileDocument HOT 1
- Remove Travis from all ReSwift repos? / How to set up GH Actions
- ReSwift 7 Roadmap HOT 20
- Docs: Update outdated and vulnerable jQuery version HOT 3
- Array as a State HOT 1
- Clarification on Single Store object for an application. HOT 1
- Change visibility of Store from 'open' to 'public final'? HOT 2
- SIGSEGV on state.didSet HOT 4
- Using Inject with ReSwift HOT 1
- Testing: Waiting for store.dispatch() to complete HOT 2
- Huge CPU gap between ReSwift Store vs just SwiftUI ObservableObject HOT 1
- Crash: sometimes will crash at this point, what can i do to find the root cause HOT 11
- Crash when dispatching actions from inside StoreSubscriber.newState() HOT 2
- How to use a state on recursive screens? HOT 4
- Filter on updates not working HOT 3
- When do you upgrade ReSwiftRouter ? Now,ReSwiftRouter just depends ReSwift 5.0.0, but lasted ReSwift is 6.1.1 HOT 2
- Privacy Manifest HOT 2
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 reswift.