介绍
Redux仍然被认为是一个臭名昭著的很难与入门级开发人员合作的图书馆,尽管占主导地位。本文旨在解释redux的基础。
为什么开发人员避免Redux
以下因素可能是开发人员倾向于避免redux的原因:
- 巨大的样板代码
- 陡峭的学习曲线
即使上述原因Redux仍然是企业,初创企业和独立开发人员中最常用的州管理库之一。
中的一个这样的企业。REDUX架构
虽然Redux的样板是开发人员避免使用它的主要原因之一,但DOE具有简单的体系结构。从而简化了应用程序中管理状态的整个过程。
Redux体系结构由三个基本组件组成:
-
Store
-
还原
-
动作
店铺
商店本质上是一个存储应用程序全局状态的容器。 Redux应用程序中只能有一个商店。保存在Redux商店中的数据无法更改。更改已经存储在Redux商店中的数据的唯一方法是派遣操作。
在引擎盖下,Redux Store只是一个普通对象,其中包含可以在应用程序中所有级别访问的状态数据。但是,该商店有一些控制状态数据流的特殊方法。
最重要的方法包括:
-
getState()
-
dispatch()
-
subscribe()
getState() 方法返回商店中的状态数据树。
dispatch() 方法用于向商店派遣操作以更改应用程序中存储的数据。它采取行动作为参数。
subscribe() 方法允许我们运行回调功能,派遣操作。这提供了一种通过调用 getState() 方法来获取最近数据的方法。
streateStore() 功能使我们能够通过将还原函数作为参数创建商店。
import { createStore } from "redux"
const store = createStore(reducer)
减速器
还原器是一个包含状态数据如何保存在商店中的逻辑的函数。还原函数只需将当前状态和派遣动作作为参数,并根据参数返回新状态。
下面的代码显示了还原函数的基本实现。
const initialState = {value: 0}
const myReducer = (state=initialState, action) => {
if(action.type === "INCREMENT"){
return {
...state,
value: state.value + 1
}
}
}
您可以看到,初始状态变量表示应用程序中的当前状态,并根据派遣的操作返回新状态。
但是,Redux应用程序通常具有多个还原器,每个还原器都存储独特的数据,以用于应用程序的不同部分。幸运的是,Redux为我们提供了 combinereducer() 函数。
combinereducer() 函数采用一个对象,其值是减少函数并返回单个还原器。这有助于具有大型代码库的项目,其中需要模块化以进行易于维护。
const combination = combineReducers({
posts: postReducer,
counts: countReducer
})
可以使用 comminereducers中提供的键 函数轻松访问每个还原器中的状态。
由于还原器是纯函数,因此必须观察到以下规则:
-
还原功能不应包含诸如异步函数之类的副作用。
-
还原器不应直接修改当前状态。
-
要修改当前状态,还原器应制作当前状态的副本,并将修改返回为新状态。
但是,有人可能会问,如果还原器无法运行异步功能,那么如何处理Redux应用程序中的数据获取?这是中间Wares进来的地方。
中间
中间件是在派遣操作和到达还原之前执行的函数。反过来,该中间件为运行异步功能和其他副作用,尤其是数据获取提供了一个环境。然后将来自副作用函数的结果数据传递给还原器以完成数据操作周期。
简而言之,还原器确定状态数据是如何更改的,中间件拦截动作在传递给还原器之前。
行动
动作只是触发状态变化的事件。他们有点定义了应用程序中的特定任务。例如,假设计数器应用程序具有用于增加和减小计数变量的按钮,可以将计数变量的递增和减少的任务视为REDUX中的操作。
在redux中,动作是一个普通的javaScript对象,具有两个属性: type 和有效载荷。
-
类型属性描述要派遣的动作。
-
有效载荷属性允许我们将一些数据附加到操作对象,以便我们可以在还原器中访问它以将其保存在商店中。
以下是Redux动作的简单实现。
const action = {
type: "INCREMENT"
}
const anotherAction = {
type: "SAVE_TODO",
payload: "Get Groceries"
}
如果我们考虑上面代码中的第二个操作,我们可以编写一个还原功能以访问有效载荷并将其保存在商店中。可以在下面找到实施。
const initialState = {todos: []}
const anotherReducer = (state=initialState, action) => {
if (action.type === "SAVE_TODO"){
return {
...state,
todos: [...state.todos, action.payload]
}
}
}
如果不提及动作创造者,这一方面将是不完整的。
动作创建者是返回操作的函数。动作创造者允许我们飞行创建动作。
const actionCreator = (type, payload) => {
return {
type,
payload
}
}
我们现在可以通过将必要的参数传递到函数来轻松创建操作。
const customAction = actionCreator("DELETE_TODOS", "Buy Groceries")
// returns {type: "DELETE_TODOS", payload: "Buy Groceries"}
使用上述实现,我们可以动态传递有效载荷。
将其缝合在一起
此刻,您应该掌握Redux的基本概念。通过在Redux中构建一个简单的计数器应用程序,我们走得更远。
该应用程序将具有以下内容:
-
html模板
-
两个动作,用于增加和减少
-
动作的还原函数
-
持续数据的商店
我们从创建UI模板开始。我们可以决定使用商店中的默认值,但是在这种情况下,我将在html中编写默认值。
<h1 id="target">0</h1>
<button id="increment">Increment</button>
<button id="decrement">Decrement</button>
然后我们创建还原函数。
const countReducer = (state={value: 0}, action) => {
if(action.type === "INCREMENT"){
return {
...state,
value: state.value+1
}
} else if(action.type === "DECREMENT"){
return {
...state,
value: state.value-1
}
} else {
return state
}
}
作为经验法则,如果操作在还原功能中不匹配,则应始终返回当前状态。
然后,我们继续创建商店并使用 subscribe() 在派遣操作时更新DOM的方法。
const store = createStore(countReducer)
store.subscribe(() => {
const { count } = store.getState()
document.querySelector("#target").innerText = count
})
最后,我们创建操作并在单击按钮时派遣它们。
const increaseCount = {type: " INCREMENT"}
const decreaseCount = {type: "DECREMENT"}
document.querySelector("#increment").onclick = () => {
store.dispatch(increaseCount)
}
document.querySelector("#decrement").onclick = () => {
store.dispatch(decreaseCount)
}
下图显示了完整的实现。
结论
节省其巨大的样板,Redux可以大大简化代码可维护性,尤其是对于具有大型代码库的项目。
其他概念将在随后的文章中进行讨论。
如果您觉得这篇文章有帮助,请在其他网络技术上发表评论和建议。
快乐学习!