揭开Redux的神秘面纱

要查看我们的第一步,我们将在store文件夹中创建一个Barrel文件,该文件将导出Store的所有内容,我们将在app.ts中使用名称fromStore导入此文件,我们将创建Store的新实例使用像reduce和空状态的空对象。

最后,我们将制作应用程序状态值的console.log。

SRC / app.ts

揭开Redux的神秘面纱

如果我们刷新浏览器,我们应该看到我们在控制台中定义的初始状态。

揭开Redux的神秘面纱:行动

我们将创建第一个操作,以便在从“添加播放器”按钮执行时更新商店的状态。

动作总是有一种类型的东西,比如字符串,也可以有一个有效负载。为了执行,我们的Store必须有一个名为

dispatch - 一种将此操作作为参数接收的约定。

src/models/store.ts

揭开Redux的神秘面纱

src/store/store.ts

揭开Redux的神秘面纱

目前,我们将把dispatch方法中的状态更改为 玩家,因为减速器将负责稍后将开发的过程。

为了改变状态,必须以不可变的方式完成,为此,我们将生成一个新对象,它将使用扩展运算符将先前状态与新玩家的状态合并。我们还在方法中添加了console.log, dispatch 以查看应用程序的状态是否已正确修改。

最后,在我们的app.ts文件中,我们从初始状态中删除console.log,通过执行dispatch 带有类型的方法从事件侦听器方法更改console.log ,并对播放器进行负载。

SRC / app.ts

揭开Redux的神秘面纱

现在,我们应该验证,在我们添加新玩家时,在控制台中,状态被正确修改。

揭开Redux的神秘面纱:减速器

在这部分中,我们为玩家创建了一个减速器。

src/store/reducers.ts

揭开Redux的神秘面纱

src/models/Player/state.ts

揭开Redux的神秘面纱

可以想象,我们可以在州内拥有多个属性。我们已经使用loaded属性创建了一个初始状态,该属性将指示玩家是否已加载(例如,HTTP调用),并且加载将指示它是否在该进程中。

这两个属性将不会被使用,因为我们没有任何异步调用来更改此状态,但它可以作为一个示例来更好地了解此管理提供给我们的内容以及在控制台中查看更多数据。我们还将创建属性数据,该数据将是一个数组,我们将所有参与者传递的值存储在Store的实例中以获取示例数据。

我们还将创建一个属性数据,该数据将是一个数组,我们将所有参与者传递的参数值存储到Store实例以获得示例数据。

该 playersReducer 函数接收第一个状态参数,该参数默认具有我们创建的初始状态,并且作为第二个参数,它接收一个动作,正如我们已经解释的那样,该动作具有类型和可选的有效载荷。

在内部,我们将使用开关评估操作的类型,作为测试用例,我们将在按钮事件中添加我们正在使用的类型“ADD_PLAYER”。我们用我们收到的有效负载(在这种情况下是播放器)组成新数据状态,最后,我们以不可变的方式返回修改状态的值。

现在我们需要注册这个reducer并将reducciones.ts中的所有内容导出到Barrel文件并将其导入app.ts.

我们创建一个名为constant的常量 reducers, 它是一个将item(players)赋值给reduce函数的对象。学习Redux模式时,其中一个有趣的部分是我们可以说我们需要几个可以改变Store状态不同部分的Reducer。

现在我们可以用新的对象reducers替换Store实例的reducers参数。

SRC / app.ts

揭开Redux的神秘面纱

在我们商店的构造函数中,我们将第一个参数绑定到reducers,在调度方法中,我们可以通过名为reduce的方法更改状态的修改。我们不应该把它与数组的原型简化混淆 - 它是我们班级的一个功能。使用存储的当前状态和已执行的操作调用Reduce。

SRC /store/ store.ts

揭开Redux的神秘面纱

接下来是一个重要的部分,所以要注意。

首先,记住我们的对象减速器:

SRC / app.ts

揭开Redux的神秘面纱

reduce方法负责生成具有与对象reducers相同的键的对象,但是将函数reducer的返回值指定为分配的每个键的值。

在这种情况下,该功能 playersReducer被赋予状态和动作。我们使用开关评估操作,如果它返回修改状态或未修改状态。

传递给的状态是 playersReducer 特定的迭代器(即密钥的最后一个值),因此它不能访问我们Store的其他状态。通过这种方式,我们获得了商店的新状态。

SRC / app.ts

揭开Redux的神秘面纱

为了完成这一部分,我们已经用构造函数中的状态绑定替换了一个使用空操作的reduce调用,并且我们在分配给事件的事件中调度之后添加了一个console.log的应用程序状态值。按钮。

揭开Redux的神秘面纱:存储订阅

到目前为止,我们已经完成了我们的商店,但我们对DOM完全没有做任何事情。我们不会更新元素或显示信息。

如果我们去商店,我们会看到我们已经覆盖了减压器,我们已经涵盖了应用程序的状态,但不包括订阅。

首先,我们将为构造函数中的订阅分配一个空数组。接下来,我们将创建一个订阅方法,允许我们在应用程序的任何位置接收来自商店的更改。这个方法将做的是接收一个函数,将它作为订阅者添加到数组,并调用每个订阅者传递商店的价值,我们的应用程序的状态。让我们调用这个调用过程 notify。

此外,我们会在每次通话时通知所有订户, dispatch 以便每次修改时都会收到新状态。

SRC /store/ store.ts

揭开Redux的神秘面纱

接下来,我们将从eventListener中删除console.log,我们将在app.ts文件中进行订阅,我们将把它作为一个参数来接收一个创建console.log的函数。我们作为参数传递的是每次notify 内部调用时运行我们的商店的内容 。

SRC / app.ts

揭开Redux的神秘面纱

如果我们刷新浏览器,我们将看到控制台打印初始状态,并且当我们添加播放器时,我们的订户使我们成为具有应用程序新状态的console.log。

揭开Redux的神秘面纱:可视化

所有这一切都开始形成,但为了让它更加华而不实,我们将在DOM上添加行为,并使用相应的按钮创建一个取消订阅方法,这样我们就不会有内存泄漏订阅商店,无论我们是否更改在这个场景中,我们消除了组件,我们重新渲染它或者其他可能给我们带来这个问题的原因。

我们将创建一个函数, renderPlayers, 这将使我们能够反复添加元素与类元素UL里面的DOM, players。

该功能负责通过参数接收玩家列表,向DOM添加玩家总数,并且对于每个玩家,添加具有玩家姓名和删除按钮的列表项。此外,我们将通过参数更改我们传递给它的函数以订阅这个新函数,我们将订阅分配给变量unsubscribe。

揭开Redux的神秘面纱

它不是在性能方面更新DOM的最正确方法,但对于我们的示例,它是可以的。

对unsubscribe 变量的预订分配将允许我们从Store的数组预订中删除此函数,以便在notify() 执行该方法时 它不再在内部,因此不会运行。为了做到这一点,我们只需要在subscribe方法中返回一个函数,该函数使用一个简单的过滤器来处理这个任务。

SRC /store/ store.ts

揭开Redux的神秘面纱

最后,为了证明我们可以取消订阅,我们将在HTML的末尾创建一个按钮,我们将添加一个执行此功能的事件。

揭开Redux的神秘面纱

SRC / app.ts

揭开Redux的神秘面纱

有了这个,我们可以进入浏览器,添加播放器,查看DOM的更新方式,点击“取消订阅”按钮,看看DOM如何停止更新,即使使用控制台,我们也可以看到状态如何不断变化。

在这一点上,我们可以说我们已经完成了Redux的实现。为了完成我们神秘的Redux示例,我们应该在reducer中添加更多动作评估,以便以预期的方式修改状态。

SRC /store/ reducer.ts

揭开Redux的神秘面纱

此新评估负责过滤通过操作以不可变方式接收的播放器。

我们最终通过定位事件元素并将分配给该data-player 属性的播放器调度REMOVE_PLAYER,将事件添加到玩家列表中 。

揭开Redux的神秘面纱

揭开Redux的神秘面纱:结论

我们可以看到,它是一个简单的库,我们可以用它来管理我们的应用程序的状态。我们一步一步地消除了它背后的所有神秘面纱。现在我们只需开发工具,使我们在使用它时可以拥有更多功能或更少的冗长。


分享到:


相關文章: