npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pluto-hooks

v1.0.2

Published

一个好用的react hook工具库

Downloads

6

Readme

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设为truesetFalse:将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

管理当前全部的cookiegetCookie: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

设置并管理一个localStoragedefaultValue为初始值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:将状态值修改为defaultValuesetRight:将状态值修改为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和stateexample:

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即可获取到最新的上下文