高阶组件
什么是高阶函数
高阶函数式至少满足下面一个条件的函数
- 接受至少一个函数作为参数
- 输出函数作为结果
接受函数作为参数
// 传入函数来指定把列表数据转换成对应输出的数据
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 !==