Supported Swift Versions: Swift 4.2, Swift 5.0, Swift 5.3
When ReSwift is a Redux-like implementation of the unidirectional data flow architecture in Swift, ReSwift-Thunk is like redux-thunk.
// First, you create the middleware, which needs to know the type of your `State`.
let thunkMiddleware: Middleware<MyState> = createThunkMiddleware()
// Note that it can perfectly live with other middleware in the chain.
let store = Store<MyState>(reducer: reducer, state: nil, middleware: [thunkMiddleware])
// A thunk represents an action that can perform side effects, access the current state of the store, and dispatch new actions, as if it were a ReSwift middleware.
let thunk = Thunk<MyState> { dispatch, getState in
if getState!.loading {
return
}
dispatch(RequestStart())
api.getSomething() { something in
if something != nil {
dispatch(RequestSuccess(something))
} else {
dispatch(RequestError())
}
}
}
// A thunk can also be a function if you want to pass on parameters
func thunkWithParams(_ identifier: Int) -> Thunk<MyState> {
return Thunk<MyState> { dispatch, getState in
guard let state = getState() else { return }
if state.loading {
return
}
api.getSomethingWithId(identifier) { something in
if something != nil {
dispatch(RequestSuccess(something))
} else {
dispatch(RequestError())
}
}
}
}
// As the thunk type conforms to the `Action` protocol, you can dispatch it as usual, without having to implement an overload of the `dispatch` function inside the ReSwift library.
store.dispatch(thunk)
// You can do the same with the Thunk that requires parameters, like so
store.dispatch(thunkWithParams(10))
// Note that these actions won't reach the reducers, instead, the thunks middleware will catch it and execute its body, producing the desired side effects.
The ExpectThunk
helper, available as a CocoaPods subspec, allows for testing the order and actions of dispatch
as well as the
dependencies on getState
.
ExpectThunk(thunk)
.getsState(RequestState(loading: false))
// If the action is Equatable it will be asserted for equality with `dispatches`.
.dispatches(RequestStart())
.dispatches { action in
XCTAssert(action.something == expectedSomething)
}
.wait() // or simply run() for synchronous flows
ReSwift-Thunk requires the ReSwift base module.
You can install ReSwift-Thunk via CocoaPods by adding it to your Podfile
:
target 'TARGET' do
pod 'ReSwiftThunk'
end
target 'TARGET-TESTS' do
pod 'ReSwiftThunk/ExpectThunk'
end
And run pod install
.
If the ExpectThunk
subspec is used, the tests target cannot be nested in another target due to current limitations. The tests target must
be a standalone target as shown in the snippet above.
You can install ReSwift-Thunk via Carthage by adding the following line to your Cartfile
:
github "ReSwift/ReSwift-Thunk"
You can install ReSwift-Thunk via Swift Package Manager by adding the following line to your Package.swift
:
import PackageDescription
let package = Package(
[...]
dependencies: [
.Package(url: "https://github.com/ReSwift/ReSwift-Thunk.git", majorVersion: XYZ)
]
)
Import testing support by importing ReSwiftThunkTesting
import ReSwiftThunkTesting
After checking out the project run pod install
to get the latest supported version of SwiftLint, which we use to ensure a consistent style in the codebase.
You can find all the details on how to get started in the Contributing Guide.
ReSwift-Thunk Copyright (c) 2018 ReSwift Contributors. Distributed under the MIT License (MIT). See LICENSE.md.
link |
Stars: 106 |
Last commit: 2 years ago |
Fixes:
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics