-
Notifications
You must be signed in to change notification settings - Fork 1
EffectID
A property wrapper that generates a hashable value suitable to identify Effect's.
@propertyWrapper
public struct EffectID: Hashable These identifiers can be bound to the root Store executing the Reducer that produces
the Effect's. This can be conveniently exploited in document-based apps for example, where
you may have multiple documents and by extension, multiple root Store's coexisting in the
same process.
In order to bind the identifiers to a store, you need to namespace their root reducer using the
Reducer.namespace() methods. You don't need to declare a namespace if you're using only one
instance of a root store in your application.
The value returned when accessing a property wrapped with this type is an opaque hashable value
that is constant across Reducer's runs, and which can be used to identify long-running or
cancellable effects:
Reducer<State, Action, Environment> { state, action, environment in
@EffectID var timerID
switch action {
case .onAppear:
return
.timer(id: timerID, every: 1, on: environment.mainQueue)
.map { _ in Action.timerTick }
case .onDisappear:
return .cancel(id: timerID)
case .timerTick:
state.ticks += 1
return .none
}
}These property wrappers can be used without arguments, but you can also provide some contextual data to parametrize them:
Reducer<State, Action, Environment> { state, action, environment in
@EffectID var timerID = state.timerID
…
}If you want to share an EffectID across reducers, you should define it as a property in any
shared type. You can even use the EffectID type itself to declare a shared identifier:
extension EffectID {
@EffectID public static var sharedID
}
// And access it as inside reducers as:
EffectID.sharedIDReducer<State, Action, Environment> { _, _, _ in
@EffectID var id1 = "A"
@EffectID var id2 = "A"
// => id1 != id2
}Two identifiers are equal iff they are defined at the same place, and with the same contextual data (if any).
Hashable
Initialize an EffectID carrying some user-defined payload.
public init<UserData>(
wrappedValue: UserData,
file: StaticString = #fileID,
line: UInt = #line,
column: UInt = #column
) where UserData: Hashable The EffectID.Value returned when accessing this property is as unique and stable as the
value provided. You can assign a value when you want to parametrize the identifier with some
State-dependant value for example:
let appReducer = Reducer<AppState, AppAction, AppEnvironment> { state, action, env in
@EffectID var timerId = state.timerID
switch action {
case .startButtonTapped:
return Effect.timer(id: timerId, every: 1, on: env.mainQueue)
.map { _ in .timerTicked }
case .stopButtonTapped:
return .cancel(id: timerId)
case let .timerTicked:
state.count += 1
return .none
}@EffectID var id1 = "A"
@EffectID var id2 = "A"
// => id1 != id2Initialize an EffectID that returns a unique and stable EffectID.Value when accessed.
public init(
file: StaticString = #fileID,
line: UInt = #line,
column: UInt = #column
) You don't need to provide any value:
let appReducer = Reducer<AppState, AppAction, AppEnvironment> { state, action, env in
@EffectID var timerId
switch action {
case .startButtonTapped:
return Effect.timer(id: timerId, every: 1, on: env.mainQueue)
.map { _ in .timerTicked }
case .stopButtonTapped:
return .cancel(id: timerId)
case let .timerTicked:
state.count += 1
return .none
}public var wrappedValue: Value Generated at 2022-06-03T18:53:26+0000 using swift-doc 1.0.0-rc.1.