-
Notifications
You must be signed in to change notification settings - Fork 2
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.sharedID
Reducer<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 != id2
Initialize 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.