使用选择器在JavaScript中计算派生状态

国家管理具有挑战性。 通过确保我们不在状态中存储任何冗余信息,我们可以减少挑战。 我什么意思 假设在我们的程序中,我们需要弄清楚是否将允许人们进入我们的酒吧。 我们可以通过检查某人的几个属性来确定这一点:我们可以查看他或她的年龄(年龄在21岁或以上的任何人都可以进入律师行),或者可以查看他或她是否是律师行的雇员(全部禁止酒吧员工进入,无论年龄大小)。 现在,我们可以将所有这些信息存储在状态对象中:

const state = {
  name: "Joe" ,
  age: 15 ,
  employee: false ,
  allowedIn: false
};

这里的问题是, allowedIn可以很容易地从ageemployee得出,这意味着该信息在技术上是多余的。 这是最成问题的,因为它为我们的国家提供了自相矛盾的机会。

介绍选择器

我们可以使用选择器来解决此问题。 选择器是将状态作为属性并返回派生状态值的函数。 让我们看看是否可以创建一个选择器来替换我们的allowedIn属性。

const state = {
  name : "Joe" ,
  age : 15 ,
  employee : false
};
const allowedIn = state => state.age >= 21 || state.employee;

现在我们看到,如果我们需要确定是否允许该人进入我们的酒吧,我们可以简单地使用调用allowedIn(state)的布尔结果!

使用可组合选择器进一步深入

现在,如果我们有一些更复杂的要求怎么办? 也许我们需要根据是否允许他们进入酒吧以及他们是否友好来做出一个名为highFiveThem的决定。 首先,让我们假装一个新的状态对象,其中包括它们是否友好。

const state = {
  name : "Judy" ,
  age : 22 ,
  employee : false ,
  isFriendly : true
};

我们的决策不仅不再基于状态对象,而且还基于另一个选择器的结果。 这是我们开始使用高阶函数来组成其他选择器的地方。 让我们看一下这在实践中是如何工作的,然后我们可以窥视一下。

const state = {
  name : "Judy" ,
  age : 22 ,
  employee : false ,
  isFriendly : true
};
const allowedIn = state => state.age >= 21 || state.employee;
const isFriendly = state => state.isFriendly;
const highFiveThem = createSelector(
    allowedIn,
    isFriendly,
    (allowedIn, isFriendly) => allowedIn && isFriendly;
)
highFiveThem(state);
// true

本质上,这将计算allowedIn(state)isFriendly(state)选择器的结果,并将这些输入传递给传递给createSelector的最终函数。

在学术上,让我们看一下这个高阶函数如何工作。

const createSelector = ( ...funcs ) => {
  const last = funcs.pop();
  return state => {
    const inputs = funcs.map( func => func(state));
    return last(...inputs);
  };
};

工作原理:

  • createSelector函数接受任何数目的funcs
  • 我们创建一个名为last的变量来存储传递给createSelector的最后一个函数,因为它将是使用所有先前函数的结果的变量。
  • 我们返回一个函数(我们的新选择器!)。
  • 每当执行该函数时,我们都会映射所有输入函数,以根据传递的state确定其结果。
  • 给定所有先前函数的结果,我们返回last函数的值。

很整洁吧?

关于效率的思考

许多选择器库(例如,针对Redux的Reselect)都包含其他功能,以记住选择器结果。 这是因为,如果选择器的输入没有从根本上改变,重新计算选择器的效率将很低。 在此处映射我们的记忆功能有点超出范围,但是请记住,由于这种优化,使用其中一个库可能会有所益处(与滚动您自己的选择器解决方案相比)。

谢谢!

From: https://hackernoon.com/calculating-derived-state-in-javascript-using-selectors-7f6ce06ac247

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值