Coder Social home page Coder Social logo

Comments (5)

Ben-G avatar Ben-G commented on May 11, 2024

@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:

  1. Provide initial state and provide reducer that assumes initialized state
  2. 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.

mortyccp avatar mortyccp commented on May 11, 2024

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.

mortyccp avatar mortyccp commented on May 11, 2024
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 Reducers 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.

Ben-G avatar Ben-G commented on May 11, 2024

@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.

mortyccp avatar mortyccp commented on May 11, 2024

After switching into the solution @Ben-G suggested in #90, the problem solved cleanly.

from reswift.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.