redux 引入antd_使用redux引入swiftui应用程序的全局状态管理

redux 引入antd

State management is an essential part of any SwiftUI application. SwiftUI provides several built-in ways for managing state, which includes @State, @EnvironmentObject, @Binding and @StateObject.

状态管理是任何SwiftUI应用程序的重要组成部分。 SwiftUI提供了几种内置的状态管理方式,包括@ State,@ EnvironmentObject,@ Binding和@StateObject。

@EnvironmentObject does manage global state, but it does not provide any structure. In this post, you will learn how to use Redux to organize the flow of your global state.

@EnvironmentObject确实管理全局状态,但不提供任何结构。 在本文中,您将学习如何使用Redux来组织全局状态流。

什么是全球状态? (What is Global State?)

Global state, represents the state that can be accessed and updated by any view/component. The main purpose of the global state is to streamline the communication between components. This means that instead of passing data up or down a complex hierarchy, views/components can simply read and update the data maintained by a global store.

全局状态,表示任何视图/组件均可访问和更新的状态。 全局状态的主要目的是简化组件之间的通信。 这意味着视图/组件可以简单地读取和更新全局存储所维护的数据,而无需在复杂的层次结构中上下传递数据。

了解Redux Flow (Understanding Redux Flow)

Redux flow depends on several different components working together. These components consists of the following:

Redux流程取决于几个不同的组件一起工作。 这些组件包括以下内容:

Store: This is a redux store, which maintains the global state.

商店 :这是一个Redux商店,用于维护全局状态。

Reducer: Reducer is used to update the global state. Reducer is the only one who can update the global state. One application can consists of multiple reducers but in the end all reducers are combined together.

Reducer :Reducer用于更新全局状态。 Reducer是唯一可以更新全局状态的工具。 一个应用程序可以包含多个减速器,但最终所有减速器都组合在一起。

Action: Actions are dispatched from the store, which goes to the reducer and finally updates the global state.

动作 :动作是从存储库中分派的,该存储库将到减速器,最后更新全局状态。

There are other concepts including Action Types, Action Creators and Middleware, but for now we will start with a basic store.

还有其他一些概念,包括动作类型,动作创建者和中间件,但是现在我们将从基本商店开始。

Here is the basic Redux Flow Diagram to show different components in action.

这是基本的Redux流程图,显示了运行中的不同组件。

Image for post

设置商店 (Setting Up Store)

We will start by creating the global store. The store depends on the reducer, so we must create a reducer instance, whose job is to update the store. There are several ways of creating a reducer, but in the most simplistic form, a reducer is just a function.

我们将从创建全球商店开始。 商店依赖于reducer,因此我们必须创建一个reducer实例,其工作是更新商店。 创建还原器有多种方法,但是以最简单的形式,还原器只是一个函数。

func reducer(state: State, action: Action) -> State {return state
}

The job of the reducer is to take in the current state and action and then return the new state. As, you can see our reducer simply returns the current state so needless to say it is kind of useless reducer. Don’t worry we will update the code shortly.

减速器的工作是获取当前状态和操作,然后返回新状态。 正如,您可以看到我们的化简器仅返回当前状态,所以不用说它是一种无用的化简器。 不用担心,我们很快就会更新代码。

The state instance represents the global state. You can put anything you want in the state, but we are going to start with storing a simple counter value.

状态实例代表全局状态。 您可以将任何所需的状态置于状态中,但是我们将从存储一个简单的计数器值开始。

struct State {var counter = 0
}

Next, let’s move on to the Store. Store is responsible for dispatching actions which will reach the reducer, where reducer will finally update the global state. The developer working on the Redux app, will mainly interact with the store.

接下来,让我们进入商店。 Store负责调度将到达reducer的动作,reduce最终将在其中更新全局状态。 使用Redux应用程序的开发人员将主要与商店互动。

typealias Reducer = (State, Action) -> Stateclass Store: ObservableObject {var reducer: Reducer@Published var state: Stateinit(reducer: @escaping Reducer, state: State = State()) {self.reducer = reducerself.state = state
}func dispatch(action: Action) {self.state = reducer(state, action)print(self.state)
}
}

As you can see in order to create a Store, we need to pass in a reducer. If the state is not passed then we will use a default instance of the state.

如您所见,为了创建商店,我们需要传入一个reducer。 如果状态没有通过,那么我们将使用状态的默认实例。

At present we don’t have any actions to dispatch. Let’s create a basic IncrementAction as shown below.

目前,我们没有任何要分派的动作。 让我们创建一个基本的IncrementAction,如下所示。

protocol Action { }struct IncrementAction: Action { }

Once, we have actions created we can update the global state based on those actions. Each action can update a slice of the global state.

一旦创建了动作,就可以基于这些动作来更新全局状态。 每个动作可以更新全局状态的一部分。

func reducer(state: State, action: Action) -> State {var state = state switch action {case _ as IncrementAction:
state.counter += 1default:break
}return state
}

As you can see the reducer function checks for a particular action and then only updates that part/slice of the global state. The state property in Store is marked with @Published, which means anytime you change the state it will notify all the listeners.

如您所见,reducer函数检查特定动作,然后仅更新全局状态的该部分/切片。 Store中的state属性标记有@Published,这意味着只要您更改状态,它就会通知所有侦听器。

Finally, we have to make sure that we inject the store to our root view. This can be done in the YourAppNameApp.swift (Xcode 12) file or SceneDelegate.swift (Xcode 11).

最后,我们必须确保将商店注入到根视图中。 可以在YourAppNameApp.swift(Xcode 12)文件或SceneDelegate.swift(Xcode 11)中完成此操作。

import SwiftUIlet store = Store(reducer: reducer)@mainstruct HelloReduxApp: App {var body: some Scene {WindowGroup {ContentView().environmentObject(store)
}
}
}

In the above code, we have injected the global store in the root view, as an environment object. This means it will be available to the root view and all the children of the root view.

在上面的代码中,我们已将全局存储作为环境对象注入到根视图中。 这意味着它将对根视图及其所有子视图可用。

Views contained in a modal are not part of the hierarchy. This means, you will manually have to inject the store through environmentObject to those views.

模态中包含的视图不属于层次结构。 这意味着,您将必须手动通过environmentObject将商店注入这些视图。

调度动作和更新视图 (Dispatching Actions and Updating Views)

At this point we have configured our global store. The next step is to read values from global state and update the global state.

至此,我们已经配置了全局存储。 下一步是从全局状态读取值并更新全局状态。

First, we create a store property inside ContentView and decorate it with @EnvironmentObject property wrapper. This allows us to access the store from right inside our view.

首先,我们在ContentView中创建一个store属性,并使用@EnvironmentObject属性包装器对其进行装饰。 这使我们可以从视图内部直接访问商店。

struct ContentView: View {@EnvironmentObject var store: Store ... code 
}

Then, we read the property from the global store and display it in the Text view as shown.

然后,我们从全局存储中读取该属性,并将其显示在“文本”视图中,如图所示。

struct ContentView: View {@EnvironmentObject var store: Store var body: some View {VStack {Text("\(store.state.counter)").padding()Button("Increment") {// dispatch action 
}
}
}
}

If you run the app, you will see the value of 0 displayed in the Text view. This is because the global state is initialized with counter value = 0.

如果运行该应用程序,您将在“文本”视图中看到显示的值为0。 这是因为全局状态是使用计数器值= 0初始化的。

In order to update the global state, we need dispatch an action.

为了更新全局状态,我们需要调度一个动作。

Button("Increment") {
store.dispatch(action: IncrementAction())
}

Once, the button is pressed, an action will be dispatched. The action will reach the reducer, where it will finally update the global state.

一旦按下按钮,将分派一个动作。 该操作将到达减速器,在此它将最终更新全局状态。

As soon as the global state is updated, views listening to the changes will render again. This means if you have multiple views displaying data from the global state, they all will render again.

全局状态一经更新,将立即呈现监听更改的视图。 这意味着,如果您有多个视图显示来自全局状态的数据,则所有视图将再次呈现。

结论 (Conclusion)

Redux is a very common pattern used extensively in web apps. It is exciting to see how Redux can be integrated with SwiftUI applications. In the next post, we will look at how to handle asynchronous requests in Redux.

Redux是一种非常普遍的模式,广泛用于Web应用程序中。 很高兴看到Redux如何与SwiftUI应用程序集成。 在下一篇文章中,我们将研究如何在Redux中处理异步请求。

GitHub Source Code

GitHub源代码

If you like this post and want to support my work then check out my Udemy courses.

如果您喜欢这篇文章并希望支持我的工作,请查看我的Udemy课程。

翻译自: https://medium.com/@azamsharp/global-state-management-for-swiftui-apps-using-redux-introduction-f9cde402a70d

redux 引入antd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值