pointfreeco · GitHub

Thanks for the feedback @mbrandonw! Sorry for the delay, just getting back to this project now after working on something else. So removing the requirement that the dependency returns a non-nil value, and assuming it's modeled as an optional, I'm still unsure where is the appropriate place to do this using TCA:

In the situation of a user switch or logout I imagine you would recreate the base view of the application. Just seems like a good way to reset everything

Take a simplified version of the TicTacToe example:

  public var body: some ReducerProtocol<State, Action> {
    Reduce { state, action in
      switch action {
      case let .login(.loginResponse(.success))
        state = .newGame(NewGame.State())
        return .none
      case .login:
        return .none
      case .newGame(.logoutButtonTapped):
        state = .login(Login.State())
        return .none
      case .newGame:
        return .none
      }
    }
    .ifCaseLet(/State.login, action: /Action.login) {
      Login()
    }
    .ifCaseLet(/State.newGame, action: /Action.newGame) {
      NewGame()
    }
  }

Where would you handle updating the dependency in a case like this? Feels like we'd want to do it when we're changing the state between login and newGame, but we can't update dependencies there. What I'm now doing is something approximately like this:

    .ifCaseLet(/State.login, action: /Action.login) {
       Login()
          .dependency(\.currentUser, nil)
    }
    .ifCaseLet(/State.newGame, action: /Action.newGame) {
      @Dependency(\.keychain) var keychain
      NewGame()
         .dependency(\.currentUser, try? keychain.get(.currentUser)))
    }

It seems to work, but I'm not sure it's correct. The docs for transformDependency mention this warning:

The trailing closure of transformDependency(_:transform:) is called for every action sent to the reducer, and so you can expect it to be called many times in an application’s lifecycle. This means you should typically not create dependencies in the closure as that will cause a new dependency to be created everytime an action is sent.

I noticed the code above behaves the same, Login() and NewGame() reducers are recreated on every single action sent in the app, recreating both their dependencies every time, so I feel like I'm missing something about the right way to approach this.

Read the original on github.com ↗