useSet
简介
首先,set是es6新增的数据结构,相似数组,但set不能有雷同的成员,能够利用这点来给数组去重;在set内增加成员比array快,但set在排序上不如数组灵便。
useSet是一个用来治理set类型state的hook,封装了以下几个性能:
- add:减少元素
- remolve:删除某个元素
- reset:重置回初始状态
简略示例
const [set,{add,remove,reset}] = useSet<string>(['a','b']);//set为['a','b']add('c')//set为['a','b','c']remolve('b')//set为['a','c']reset()//set为['a','b']
源码剖析
import { useState } from 'react';import useMemoizedFn from '../useMemoizedFn';function useSet<K>(initialValue?: Iterable<K>) {//获取初始值:应用new Set创立一个以初始传入参数为内容的set,或者一个空set const getInitValue = () => { return initialValue === undefined ? new Set<K>() : new Set(initialValue); };//用根本的useState来封装该hook const [set, setSet] = useState<Set<K>>(() => getInitValue());//add办法:若set已有该值,则不做解决;若无,则应用set的add办法增加元素 const add = (key: K) => { if (set.has(key)) { return; } setSet((prevSet) => { const temp = new Set(prevSet); temp.add(key); return temp; }); };//remove办法:若set没有该值,则不做解决;若无,则应用set的delete办法删除元素 const remove = (key: K) => { if (!set.has(key)) { return; } setSet((prevSet) => { const temp = new Set(prevSet); temp.delete(key); return temp; }); };//reset办法:重置回初始值 const reset = () => setSet(getInitValue());//返回应用了useMemoizedFn这个hook return [ set, { add: useMemoizedFn(add), remove: useMemoizedFn(remove), reset: useMemoizedFn(reset), }, ] as const;}export default useSet;
要点剖析
该hook在return办法的时候应用了useMemoizedFn这个hook。该hook和useCallback相似。
但不同之处在于useCallback返回的是回调函数的memoized版本,当依赖项不扭转的时候,它不会更新函数,但增加依赖项的时候,函数会从新渲染,这就失去了缓存函数的意义;而useMemoizedFn解决了这个问题,能够用来缓存各种函数,并且函数的地址不会被扭转。
基于useSet的改写:useArray,实现了数组的push、pop、shift、unshift办法
在应用useSet的过程中,因为useSet的add办法是将元素间接加在set的前面,感觉想要将元素插在set后面不太灵便,于是照着该源码,简略地改编了一个useArray,实现了数组的push、pop、shift、unshift办法。
代码如下:
import { useState } from 'react';import { useMemoizedFn } from 'ahooks';function useArray<K>(initialValue?: Iterable<K>) { const getInitValue = () => { return initialValue === undefined ? new Array<K>() : Array.from(initialValue); }; const [array, setArray] = useState<Array<K>>(() => getInitValue()); const push = (...key: K[]) => { setArray((prevSet) => { const temp = Array.from(prevSet); temp.push(...key); return temp; }); }; const unshift = (...key: K[]) => { setArray((prevSet) => { const temp = Array.from(prevSet); temp.unshift(...key); return temp; }); }; const pop = () => { setArray((prevSet) => { const temp = Array.from(prevSet); temp.pop(); return temp; }); }; const shift = () => { setArray((prevSet) => { const temp = Array.from(prevSet); temp.shift(); return temp; }); }; const reset = () => setArray(getInitValue()); return [ array, { push: useMemoizedFn(push), pop: useMemoizedFn(pop), shift: useMemoizedFn(shift), unshift: useMemoizedFn(unshift), reset: useMemoizedFn(reset), }, ] as const;}export default useArray;
简略应用
const [array,{push,pop,shift,unshift,reset}] = useArray<string>(['a','b']);//set为['a','b']push('c','cc')//set为['a','b','c','cc']pop()//set为['a','b','c']...