技术分享 - React Native开发中使用高阶组件来复用逻辑

高阶组件


什么是高阶函数

高阶函数式至少满足下面一个条件的函数

  • 接受至少一个函数作为参数
  • 输出函数作为结果

接受函数作为参数

// 传入函数来指定把列表数据转换成对应输出的数据
list.map(value => <Text>{`value`'}</Text>)

// 传入指定的比较函数来指定排序算法使用的比较方法
const sortedList = list.sort(sortFunc);
本质上是传入函数,动态根据函数生成特定的数据

输出函数作为结果

import { createAction } from 'redux-action';

const updateData = createAction('UPDATE_DATA');
// 本质上返回了一个函数
// 接受输入之后执行UPDATE_DATA对应的reducer来更新store

export default {
    // 也返回了一个函数updateList, updateList根据传入的param
    // 进行网络请求,之后使用获得数据更新store
    updateList: param => (dispatch, getState) => (
        Request.post(param)
        .then(data => dispatch(updateData(data)))
    ),
};
本质上是传入数据,动态根据数据生成特定的方法

高阶组件

高阶函数的常用用法

高阶组件涉及主要为下面的用法,接受函数作为参数并返回函数作为结果,如下简单的case:

计算加权平均值,有一个列表list, 在不同的标准a,b,c, …下计算加权平均值,各个标准分别有权重函数getWeightA, getWeightB, getWeightC …

最常见的写法如下:

const weightedAvgA = (list) => {
    let sum = 0;
    for (let index = 0; index < list.length ; index += 1) {
        sum += getWeightA(list[index]);
    }
    return sum / list.length;
};

const weightedAvgB = (list) => {
    let sum = 0;
    for (let index = 0; index < list.length ; index += 1) {
        sum += getWeightB(list[index]);
    }
    return sum / list.length;
};

// ...

这种写法一个是有大量的重复代码,写起来麻烦,不容易维护,还有就是代码hardcode把获取权值的方法写死了, 如果遇到需求需要动态的定义标准时,就很麻烦了。

大家很容易想到,可以生成一个高阶函数来处理, 这个函数接受一个权重函数作为参数, 返回一个函数用于计算list的加权平均值。

const getAvgFunc = getWeight => list => (
    list.map(value => getWeight(value))
    .reduce((accu, weightedValue) => accu + weightedValue, 0)
);

const weightedAvgA = getAvgFunc(getWeightA);
const weightedAvgB = getAvgFunc(getWeightB);
const weightedAvgC = getAvgFunc(getWeightC);
// ...  

React 组件 - 函数本质

我们平常声明的大量的React函数, 本质上也可以抽象成函数的表示

View = ReactFunc(props)

如同我们常见的React纯函数组件, 当然很多组件并不能表示为这个这种状态, 诸如使用内部使用state或者诸如this.a = 10这样的内部变量。

解决方法就是把各个组件里面的this.a = 10这样的内部变量弄成state,之后再把state提取到组件store储存起来,之后使用props把这些值和修改这些值的action方法传入进去。

这样就可以应用高阶函数的原理到React组件中了。
基于上面的计算加权平均值情景, 想象我们需要开发下面一个组件, 不同的场景下权值获得函数也不一样, 有的是本地获取,有的是使用value请求远端服务器。(参考模拟器上面的场景)

| value1 | weightedValue1 |
---------------------------
| value2 | weightedValue2 |
---------------------------
| value3 | weightedValue3 |
---------------------------
| value4 | weightedValue4 |
---------------------------
average: weightedAverage

对应的显示逻辑如下

const WeightedListView = ({ weightedList, weightedAverage }) => (
  <View style={style.listContainer}>
    <View style={style.tableRow}>
      <Text style={style.raw}>{'原始数据'}</Text>
      <Text style={style.weighted}>{'加权后数据'}</Text>
    </View>
    <View style={style.tableRow}>
      <Text style={style.raw}>
        {`平均值: ${
          weightedAverage !== 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值