常用的第三方库
0.代码库
https://gitee.com/lhwz666/daily-code
1.表单校验库:formik
2.函数工具包:ramda
和函数柯里化
函数名 | 作用 | 备注 |
---|---|---|
path | 取出对象中的值 | 相当于 lodash 的 get |
path 的案例
const { path } = require("ramda");
// console.log(path(["session", "username"]).toString());
const state = {
session: {
username: "fjk",
},
};
const props = {
session: {
username: "props",
},
};
const result = path(["session", "username"])(state, props);
console.log(result); // 打印出的 state 的 fjk
3.缓存 state 的计算结果:Reselect
根据 state 中的某个值的改变来进行精确计算,而不是根据整个 state 来进行重新计算。
/**
* Basic example for the reselect library
* @see https://github.com/reactjs/reselect
*/
const { createSelector } = Reselect;
const shopItemsSelector = (state) => state.shop.items;
const taxPercentSelector = (state) => state.shop.taxPercent;
const subtotalSelector = createSelector(shopItemsSelector, (items) =>
items.reduce((acc, item) => acc + item.value, 0)
);
const taxSelector = createSelector(
subtotalSelector, // 2.15
taxPercentSelector, // 8
(subtotal, taxPercent) => subtotal * (taxPercent / 100) // 2.15*(8/100) = 0.172
);
const totalSelector = createSelector(
subtotalSelector, // 2.15
taxSelector, // 0.172
(subtotal, tax) => ({ total: subtotal + tax })
);
let exampleState = {
shop: {
taxPercent: 8,
items: [
{ name: "apple", value: 1.2 },
{ name: "orange", value: 0.95 },
],
},
};
console.log(subtotalSelector(exampleState)); // 2.15
console.log(taxSelector(exampleState)); // 0.172
console.log(totalSelector(exampleState)); // { total: 2.322 }
4.React 中的 lodash: recompose
对函数组件改造成类组件,Recompose 允许你通过添加状态,生命周期方法,上下文等来增强函数组件。
函数名 | 作用 | 备注 |
---|---|---|
lifecycle | 添加生命周期 | HOC |
compose | 借用 reduce 复合函数 | |
branch | 接受一个测试函数和一个必选左侧高阶组件和非必选的右侧高阶组件,如果测试函数为 true 则将左侧高阶组件应用于要被使用的 BaseComponent,否则将应用右高阶组件【未提供右侧的话默认呈现包装的组件】 | HOC 再次 HOC |
renderComponent | 接受一个组件并返回有一个 HOC 版本的此组件 | 利用 react 的 createFactory |
renderNothing | 根据条件来返回 null 的高阶组件 | |
compose 源代码
const compose = (...funcs) =>
funcs.reduce(
(a, b) =>
(...args) =>
a(b(...args)),
(arg) => arg
);
branch 源代码
const identity = (Component) => Component;
const branch =
(test, left, right = identity) =>
(BaseComponent) => {
let leftFactory;
let rightFactory;
const Branch = (props) => {
if (test(props)) {
leftFactory = leftFactory || createFactory(left(BaseComponent));
return leftFactory(props);
}
rightFactory = rightFactory || createFactory(right(BaseComponent));
return rightFactory(props);
};
return Branch;
};
renderComponent 源代码和案例
源代码
const renderComponent = (Component) => (_) => {
const factory = createFactory(Component);
const RenderComponent = (props) => factory(props);
return RenderComponent;
};
案例
// `isLoading()` is a function that returns whether or not the component
// is in a loading state
const spinnerWhileLoading = isLoading =>
branch(
isLoading,
renderComponent(Spinner) // `Spinner` is a React component
)
// Now use the `spinnerWhileLoading()` helper to add a loading spinner to any
// base component
const enhance = spinnerWhileLoading(
props => !(props.title && props.author && props.content)
)
const Post = enhance(({ title, author, content }) =>
<article>
<h1>{title}</h1>
<h2>By {author.name}</h2>
<div>{content}</div>
</article>
)
renderNothing 源代码和案例
源代码
import { Component } from "react";
class Nothing extends Component {
render() {
return null;
}
}
const renderNothing = (_) => Nothing;
案例 结合 branch 来进行条件渲染
// `hasNoData()` is a function that returns true if the component has
// no data
const hideIfNoData = (hasNoData) => branch(hasNoData, renderNothing);
// Now use the `hideIfNoData()` helper to hide any base component
const enhance = hideIfNoData(
(props) => !(props.title && props.author && props.content)
);
const Post = enhance(({ title, author, content }) => (
<article>
<h1>{title}</h1>
<h2>By {author.name}</h2>
<div>{content}</div>
</article>
));
5.redux-actions 来简化 redux 的使用
6. 私有项目:redux-saga-mate
函数名 | 作用 | 备注 |
---|---|---|
createAsyncAction | 创建异步的 action | 会创建一个含有唯一性 ID 的 action 以便 idOfAction 使用 |
idOfAction | 返回一个 action 的唯一 id | 默认会生成唯一性 ID,如果是已存在的 action 可以返回 action.mate.id |
withAsyncActionStateHandler | ||
7. useCallback 和 useMemo 和 memoization
useMemo: 把“创建”函数和依赖项数组作为参数传入 useMemo
,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。
useCallback: 把内联回调函数及依赖项数组作为参数传入 useCallback
,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate
)的子组件时,它将非常有用。
useCallback(fn, deps)
相当于 useMemo(() => fn, deps)
。
8.React.createFactory
React.createFactory(type);
返回用于生成指定类型 React 元素的函数
。与 React.createElement()
相似的是,类型参数既可以是标签名字符串(像是 'div'
或 'span'
),也可以是 React 组件 类型 (class 组件或函数组件),或是 React fragment 类型。
9.弹窗的显隐封装-@huse/boolean
import {useBoolean} from '@huse/boolean';
// use
const [modalVisible, {on: modalOn, off: modalOff}] = useBoolean(false);
数组第一个项是状态
第二项是对象:on off 和 toggle
on(): boolean;
off(): boolean;
toggle(value: boolean): boolean;
10.lodash/fp
的使用
pick
分拣对象的属性
const { pick } = require("lodash/fp");
const formikProps = ["as", "children"];
console.log(pick(formikProps, { as: "a", hh: "hh" })); // { as: 'a' }
omit
删除对象的属性
var object = { a: 1, b: "2", c: 3 };
_.omit(object, ["a", "c"]);
// => { 'b': '2' }
omitBy 和 pickBy
根据筛选函数来删除部分属性
const { omitBy, pickBy, isNumber } = require("lodash/fp");
const isNumber2 = (value, key) => {
console.log(value, key); // 1 a
return isNumber(value);
};
var object = { a: 1, b: "2", c: 3 };
console.log(omitBy(isNumber2)(object)); // { b: '2' }
console.log(pickBy(isNumber)(object)); // { a: 1, c: 3 }
debounce 防抖
noop 直接返回 undefined
is 开头的是判断类型的
compose 的组合函数
const { compose } = require("lodash/fp");
const print = (a) => {
console.log("1", a);
return a + "c";
};
const print1 = (a) => {
console.log("2", a);
return a + "b";
};
// 由后向前 执行的
const result = compose(print, print1)("a");
// 2 a
// 1 ab
console.log(result); // abc
11.箭头函数的 demo
const print = (num) => (_) => {
console.log({ _ }); //22
const add = (a) => () => console.log(a + num);
return add;
};
const add = (a) => () => console.log(a);
console.log(add("11").toString());
const fin = print(11)(22)(33);
console.log(fin.toString()); // 打印出函数 () => console.log(a+num)
console.log(fin()); // 44
12.数据格式化库normalizr
https://blog.csdn.net/xiaoluodecai/article/details/106845728