美文网首页
SwiftUI 中使用 Redux 设计模式

SwiftUI 中使用 Redux 设计模式

作者: evan0723 | 来源:发表于2021-05-31 13:56 被阅读0次

什么是Redux ?
ReduxJavaScript 状态容器,提供可预测化的状态管理

Redux的工作原理

redux.png
首页根据业务需求 我们创建对应 StoreActionState

Ruducer 是负责处理逻辑的函数

typealias SearchStore = Store<SearchState, SearchAction, SearchSever>
typealias Reducer<State, Action, Server> = (inout State, Action, Server) -> AnyPublisher<Action, Never>?

final class Store<State, Action, Server> : ObservableObject {
    @Published var state: State
    
    private let server: Server
    private let reducer: Reducer<State, Action, Server>
    private var effectCancellables: Set<AnyCancellable> = []

    init(initialState: State, server: Server, reducer: @escaping Reducer<State, Action, Server>) {
        self.state = initialState
        self.server = server
        self.reducer = reducer
    }
    
    func send(_ action: Action) {
        guard let value = reducer(&state, action, server) else { return }
        value
            .receive(on: DispatchQueue.main)
            .sink(receiveValue: send)
            .store(in: &effectCancellables)
    }
}

enum SearchAction {
    case searchResult(series: [Brands.Series])
    case search(text: String)
    case cancel
}

struct SearchState {    
    var searchText: String = ""
    var isSearching: Bool = false
    var didSearch: Bool = false
    var searchResult: [Brands.Series] = []
    
    var isEmpty: Bool { return searchResult.isEmpty && isSearching && !searchText.isEmpty && didSearch }
    
    mutating func clean() {
        searchText = ""
        isSearching = false
        searchResult = []
        didSearch = false
    }
}

extension Store {
    static func reducer(state: inout SearchState, action: SearchAction, server: SearchSever) -> AnyPublisher<SearchAction, Never> {
        switch action {
        case .searchResult(series: let series): state.searchResult = series
        case .search(text: let text):
            state.didSearch = true
            return server.service
                .searchPublisher(matching: text)
                .replaceError(with: [])
                .map { SearchAction.searchResult(series: $0) }
                .eraseToAnyPublisher()
        case .cancel: state.clean()
        }
        return Empty().eraseToAnyPublisher()
    }
}
SceneDelegate 注册 StoreenvironmentObject
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

        // Create the SwiftUI view that provides the window contents.
        let store = SearchStore(initialState: SearchState(), server: SearchSever(), reducer: SearchStore.reducer)
        let contentView = ContentView().environmentObject(store)

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
在View 层我们只需要添加环境变量即可 然后关联上我们对应状态的参数
struct SearchView : View {
    @EnvironmentObject var store: SearchStore
    
    private var searchText: String { return store.state.searchText }
    private var isSearching: Bool { return store.state.isSearching }
    
    var body: some View {
        HStack {
            Image(systemName: "magnifyingglass")
                .padding(.leading, 16)
            TextField("Tap here to search", text: $store.state.searchText, onEditingChanged: { value in
                if value { store.state.didSearch = false }
                withAnimation { store.state.isSearching = true }
            }, onCommit: {
                store.send(.search(text: searchText))
            })
            Button(action: {
                UIApplication.shared.windows.first { $0.isKeyWindow }?.endEditing(true)
                withAnimation {
                    store.send(.cancel)
                }
            }) {
                Image(systemName: "xmark")
                    .foregroundColor(.darkerGray)
                    .opacity(isSearching ? 1 : 0)
            }
            .padding(12)
        }
        .background(Color.lightGray)
        .cornerRadius(10.0)
        .padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
        .navigationBarHidden(isSearching)
    }
}

这里只是用Redux 在SwiftUI 中实现了一个简单的Demo, 欢迎大家来讨论!

相关文章

  • SwiftUI 中使用 Redux 设计模式

    什么是Redux ?Redux 是 JavaScript 状态容器,提供可预测化的状态管理 Redux的工作原理 ...

  • Redux For SwiftUI

    摘自《SwiftUI和Combine编程》---《SwiftUI架构》 Redux For SwiftUI 架构图...

  • Redux原理分析

    redux介绍 redux是一个针对JavaScript应用的可预测的状态管理器。 redux中的设计模式 装饰者...

  • 迭代器模式在前端的使用场景

    一、迭代器模式在Redux源码中的使用 二、迭代器模式在Koa2源码中的使用 场景一、二都是利用迭代器模式,依次调...

  • 设计模式系列(目录)

    设计模式 设计模式并没有想象中的高大上,在你平日的开发和使用中,也一定有使用到过 什么是设计模式? 设计模式(De...

  • 在 SwiftUI 中实现 Redux

    作者:Lebron链接:https://juejin.cn/post/6912251186770870286[ht...

  • react理解 ----redux

    一. Redux简介 --- fluxRedux是什么以及Redux设计和使用的三大原则Redux核心API与R...

  • Swift+Redux

    在聊Redux之前,我们先回顾一下之前我们使用过的设计模式MVC,MVVM,MVP,VIPER。如图所示,由于这些...

  • 如何快速理解使用redux

    使用redux的主要流程 首先 引入 redux 使用redux中的createStore去创建一个store 在...

  • 《松本行弘的程序世界》之设计模式

    什么是设计模式 设计模式是个编程术语,它是指设计上经常反复使用的模式。 主要的23中设计模式 Singleton模...

网友评论

      本文标题:SwiftUI 中使用 Redux 设计模式

      本文链接:https://www.haomeiwen.com/subject/myqgxqtx.html