pluto-hooks
TypeScript icon, indicating that this package has built-in type declarations

1.0.2 • Public • Published

pluto-hooks

一个好用的react hook工具库








前言

随着react16.8的发布,hook新特性随之而来,hook的到来让function组件焕发出强大的能力,足矣取代之前的class组件。函数式组件依靠useState、useEffect等hook实现变量状态维持、抽离副作用等功能。虽然原生的useEffect具有强大的功能,但是那些常用的写法每次都要手动复现一次,不但影响开发效率,而且容易出错,所以笔者将有关useEffect常用的写法都封装起来,让你的开发如鱼得水。

此项目大部分hook都是和useEffect有关,当然也有其他,开发者们可以自行选择使用

后续会继续更新更多hook的拓展功能!!

安装

yarn

yarn add pluto-hooks

npm

npm i pluto-hooks

使用

import { useEffectOnece } from "pluto-hooks";

useEffectOnece(() => {
  console.log("触发");
});

hooks介绍

effect相关

useCountUpdateEffect

第n次渲染并且deps变化才执行effect

type {
	effect:EffectCallback,
    n:number,
    deps?:DependencyList
}

useRangeUpdateEffect

在组件渲染次数为[range[0],range[1]]之间执行

type {
	effect:EffectCallback,
	deps:DependencyList,
	range:number[]
}

useCompareEffect

type {
	effect:EffectCallback,
	deps:DependencyList,
	depsEqual:(oldDeps:DependencyList,nextDeps:DependencyList) => boolean
}

第三个参数为比较函数,depsEqual的第一个参数是旧的deps数组,第二个参数为新的deps数组,该函数返回一个boolean值,为true时不执行effect,反之执行

示例
import React, { useState } from "react";
import useCompareEffect from "../index"

export default function demo() {
  const [count1, setCount1] = useState(0)
  const [count2, setCount2] = useState(0)
  const [count, setCount] = useState(0)

  const compareFn = (old,next) => {
    console.log('old,next: ', old,next);
    return old[1] === next[1]
  }

  useCompareEffect(() => {
    // 只有count2改变时会触发
    setCount(state => state + 1)
  }, [count1, count2],compareFn)

  return (
    <div>
      <h2>{count}</h2>
      <h2>{count1}</h2>
      <h2>{count2}</h2>
      <button onClick={() => {setCount1(state => state + 1)}}>count1</button>
      <button onClick={() => {setCount2(state => state + 1)}}>count2</button>
    </div>
  )
}

useDeepCompareEffect

当组件重新渲染时执行useDeepCompareEffect,该hook将对deps进行深比较,若相等则执行effect

type {
	effect:EffectCallback,
	deps:DependencyList,
}

useAsyncEffect

type {
	effect:EffectCallback,
	deps?:DependencyList
}

普通的useEffect的第一个参数是不能传入一个异步函数的,理由是 effect function 应该返回一个销毁函数(effect:是指return返回的cleanup函数),如果 useEffect 第一个参数传入 async,返回值则变成了 Promise,会导致 react 在调用销毁函数的时候报错 :function.apply is undefined。

调用useAsyncEffect,effect function即可可以传入异步函数

示例
import { useAsyncEffect } from "pluto-hooks"

function App(){
    useAsyncEffect(async () => {
        // 进行异步操作
    },[])
}

useDebounceFn

处理防抖函数

const {
  run,
  cancel,
  flush
} = useDebounceFn(
  fn: (...args: any[]) => any,
  options?: Options
);

run, cancel, flush为可执行函数

run:开始防抖地执行fn,传入run的参数会传到fn

cancel:取消执行fn

flush:立即执行fn,不用等到wait时间结束

useDebounceEffect

type {
    effect:EffectCallback,
    deps?:DependencyList,
    options:DebounceOptions
}

将传入的Effect带上防抖,options可以配置防抖参数

options参数(默认值):

[options.wait=1000] (number): 等待时间,单位为毫秒。
[options.leading=false] (boolean): 指定在延迟开始前调用。
[options.maxWait] (number): 设置 func 允许被延迟的最大值。
[options.trailing=true] (boolean): 指定在延迟结束后调用。

useThrottleFn

处理节流函数的hook

const {
  run,
  cancel,
  flush
} = useThrottleFn(
  fn: (...args: any[]) => any,
  options?: Options
);

options参数:

[options.wait=1000] (number): 等待时间,单位为毫秒。
[options.leading=true] (boolean): 指定调用在节流开始前。
[options.trailing=true] (boolean): 指定调用在节流结束后。

run, cancel, flush为可执行函数

run:开始防抖地执行fn,传入run的参数会传到fn

cancel:取消执行fn

flush:立即执行fn,不用等到wait时间结束

useThrottleEffect

将传入的Effect带上节流功能,options可以配置节流参数

type {
	effect:EffectCallback,
	deps:DependencyList,
	options:ThrottleOptions
}

options参数:

[options.wait=1000] (number): 等待时间,单位为毫秒。
[options.leading=true] (boolean): 指定调用在节流开始前。
[options.trailing=true] (boolean): 指定调用在节流结束后。

useEffectOnce

只在第一次渲染时执行

type {
	effect:EffectCallback,
}

useUpdateEffect

非首次渲染时执行

type {
	effect:EffectCallback,
	deps:DependencyList,
}

leftCycle相关

useFirstMountState

判断改组件是否是第一次渲染,返回Boolean

示例
import { useFirstMountState } from "pluto-hooks"

function App(){
    const isFirst = useFirstMountState()
    
    if(isFirst){
        // 第一次渲染要执行的
    }
}

useMount

只在第一次渲染执行传入的函数

type {
  fn: (...args: any) => void
}

useUnmount

在组件卸载时执行传入的函数

type {
  fn: (...args: any) => void
}

useUnmountedRef

维护一个ref并返回,当组件已经卸载时为true,否则为false

  • 经常用于阻止组件卸载后副作用继续执行

example:

import useUnmountedRef from "../index";
import React, { useEffect } from "react";

// 加载后马上按button,效果是三秒后没有执行setTimeout的异步操作
const MyComponent = () => {
	const unmountedRef = useUnmountedRef();
	useEffect(() => {
		setTimeout(() => {
			if (!unmountedRef.current) {  // 当前组件卸载后则不再执行某些异步操作
				console.log("component is alive");
			}
		}, 3000);
	}, []);

	return <p>Hello World!</p>;
};

state相关

useBoolean

管理一个boolean类型的state,返回当前state和4个方法
toggle:将取反
setTrue:将state设为true
setFalse:将state设为false

const [ state, { toggle, setTrue, setFalse }] = useBoolean(
  initState?: boolean,
);
  

useCookie

设置并管理一个cookie的状态
若要将cookie删除,调用useCookie()useCookie(undefined)即可

export interface cookieOPtionsType {
  domain?: string,
  path?: string,
  day?: number, // 表示过期天数,-1表示立即过期
  secure?: boolean,
  sameSite?: "strict" | "lax" | "none"
}
 
const [cookie, setCookie] = useCookie(
  key: string, 
  value?: string, 
  defaultOptions: cookieOPtionsType
)

useCookies

管理当前全部的cookie
getCookie:const cookie = getCookie(key:string)
setCookie: setCookie(key: string, value: string, options: cookieOPtionsType= {})
removeCooikeItem: removeCooikeItem(key:string)
getAllCookie:获取所有的cookie

interface cookieType {
  [key: string]: string
}

const cookieArr = getAllCookie():cookieType
const {
  getCookie, 
  setCookie, 
  removeCooikeItem, 
  getAllCookie
} = useCookies()

useGetState

可以跳出当前闭包环境获取state的最新值
返回数组的前两个元素和useState返回的没有差别,第三个函数可以实时获取state的最新值

const [state, setState, getState] = 
      useGetState<S>(initValue: S | (() => S))

useLocalStorageState

设置并管理一个localStorage
defaultValue为初始值
serializer:默认为JSON.stringify可以自定义序列化函数,每次设置值都会存储序列化后的值
deserializer:默认为JSON.parse可以自定义反序列化函数,每次取值都会进行反序列化

interface Options<T> {
  defaultValue?: T | (() => T);
  serializer?: (value: T) => string;
  deserializer?: (value: string) => T;
}

const [state, setState] = 
     useLocalStorageState<T>(key: string, options: Options<T>)

useSessionStorageState

与useLocalStorageState一样

useMap

维护一个map
可以选择传入的参数为一个二维数组作为初始值,如

[
		["key1", "hello world"],
		[123, "number type"]
]
const [map, { set, setAll, remove, reset, get }] = 
      useMap<K, T>(initialValue?: Iterable<readonly [K, T]>)

set:添加键值对
set(key: any, value: any): void

setAll:重置该map,传入二维数组

remove:移除一对键值对
remove(key: any): void

reset:重置为初始值

get:传入一个key获取value

useSet

维护一个set
传入一个数组作为初始值

const [state, { add, remove, reset }] = 
      useSet<T>(initValue?: Iterable<T>)

add:接收一个参数,为set添加值
remove:接收一个key,移除它
reset:重置为初始值

usePrevious

维护state上次的值
传入一个状态state

const previous = usePrevious<T>(state: T): T

useSetState

管理 object 类型 state 的 Hooks,用法与 class 组件的 this.setState 基本一致。
可以直接合并新旧对象

const [state, setState] = useSetState(initialState)

useToggle

维护两个状态,可以相互转换

  • 若不传入参数,则用法和useBoolean一样
  • 若值传入第一个参数,right则取left的反值(!left)

toggle:换到另一个状态
set:修改状态值
setLeft:将状态值修改为defaultValue
setRight:将状态值修改为reverseValue

const [state, { toggle, set, setLeft, setRight }] = 
      useToggle(defaultValue, reverseValue)

useUrlState

维护url的params参数,管理一个object对象,基于上面的useSetState
若要删除某个参数,将其设为undefined即可

interface paramsType {
  [key: string]: string
}

interface optionsType {
  navigateMode: "push" | "replace" 
  // push 使用history.pushState()这个API
  // replace 使用history.replaceState()这个APi
}

const [state, setState] = 
      useUrlState(initParams: paramsType, options: optionsType)

other

useEvent

使useCallback的依赖没有发生变化的情况下,它的函数能取最新的props和state
example:

export default function demo1() {
	const [count, setCount] = useState(1);
	const fn = useEvent(() => {
		setCount(state => state + 1);
		console.log(count);
	}, []);
	return (
		<button onClick={() => { fn(); }}>Click</button>
	);
}

如果fn使用useCallback包裹,那么当点击Click时打印出来的count每次都是1,这里有两个原因

  1. useState是异步的,setCount后state不会马上发生变化
  2. 当第二次点击时,因为被useCallback包裹,fn的状态还是停留在最初渲染时,而且没有依赖,所以fn的引用永远不会改变,所以fn里面的state永远都是1

使用useEvent包裹后,state即可获取到最新的上下文

Package Sidebar

Install

npm i pluto-hooks

Weekly Downloads

1

Version

1.0.2

License

MIT

Unpacked Size

177 kB

Total Files

75

Last publish

Collaborators

  • pluto-lam