自定义Hook-组件状态

强制重新渲染界面

1 .代码

// 强制重新渲染hook

// 递增一个state值,触发react进行渲染
import React,{useCallback,useState} from 'react'

export default function useForceUpdate(){
    const [,setValue]=useState(0)

    return useCallback(()=>{
        setValue(val=>(val+1)%(Number.MAX_SAFE_INTEGER-1))
    },[])
}

2 .使用

const forceUpdate=useForceUpdate()
    console.log('真的渲染了')
    function handleClick(){
        console.log('重新渲染了')
        forceUpdate()
    }

获取dom属性

import React,{useState,useEffect} from 'react'

export default function useDom(ref){
    const [dom,setDom]=useState(null)

    useEffect(() => {
        const domStyle=ref.current.getBoundingClientRect()
        setDom({
            x:domStyle.x,
            y:domStyle.y,
            left:domStyle.left,
            top:domStyle.top,
            width:domStyle.width,
            height:domStyle.height,
        })
        // 好像不能简写,简写返回的是一个domReact类型的对象,还是要这样包装一下
    }, [ref]);
    return dom
}

2 .使用:要传一个可以获取的ref进去
const domref=useRef()
    const domStyle=useDom(domref)
    console.log(domStyle)
    // 则个值一开始是0,后来计算出来才是正确的,所以这里用的时候应该判断下是否有值
    return (
        
{/* width{width} */} click-{num}
)

同步到本地存储

1 .那我也可以使用这个做全局缓存了
2 .代码
import React,{useState,useEffect} from 'react'
import { useCallback } from 'react'
export default function useStorage(key,defaultValue,keepWindowClosed){
// key:存储的key
// default;默认的值
// keepWindowClosed;窗口关闭之后是否继续保存
    const storage=keepWindowClosed?window.localStorage:window.sessionStorage

    const getStorageValue=()=>{
        try{
            const storageValue=storage.getItem(key)
            if(storageValue!=null){
                return JSON.parse(storageValue)
            }else if(defaultValue){
                const value=typeof defaultValue=='function'?defaultValue():defaultValue
                storage.setItem(JSON.stringify(value))
                return value
            }
        }catch(err){
            console.log(`useStorage 无法获取到${key}:`,err)
        }
        return undefined
    }

    const [value,setValue]=useState(getStorageValue())

    // 更新组件状态并保存到storage
    const save=useCallback((value)=>{
        setValue(prev=>{
            const finalValue=typeof value==='function'?value():value
            storage.setItem(key,JSON.stringify(finalValue))
            return finalValue
        })
        console.log(value)
    })

    // 清除状态
    const clear=useCallback(()=>{
        storage.removeItem(key)
        setValue(undefined)
    },[])
    return [value,save,clear]
}
3 .使用方法
const [num,setNum]=useState(0)
    function handleClick(){
        setNum(num+1)
        setUser(num+1)
    }
    
    function handleRemove(){
        clearUser()
    }
    // 测试函数


    const [use,setUser,clearUser]=useStorage('user')

获取上一次的props,state

import React,{useEffect,useRef} from 'react'

function usePrevious(value){
    const ref=useRef()

    useEffect(()=>{
        ref.current=value
    });

    console.log(ref.current)
    return ref.current
}

export default usePrevious

获取最新的props

1 .这个没想到哪里会用到o
2 .可以和获取上次的props进行写法比较

export default function useRefProps(props: T) {
  const ref = useRef(props)
  // 每次重新渲染设置值
  ref.current = props

  return ref
}

useToggle

import {useState} from 'react'
import { useCallback } from 'react'

export default function useToogle(defaultvalue){
    const [value,setValue]=useState(!!defaultvalue)
    const toggler=useCallback(()=>setValue(value=>!value),[])
    return [value,toggler]
}

//使用
const [isOnline,toggleOnline]=useToggle(true)

    function handleClick(){
        setNum(num+1)
    }
    
    function handleRemove(){
        toggleOnline()
    }
    // 测试函数

    return (
        <>
            
{isOnline}-{num} //布尔值是不能直接这样显示出来的,必须要像下面一样
remove{isOnline?'true':'false'}
)

useArray

1 .其实就是把python那些方法写成是js的语法
function useArray(initial?: T[] | (() => T[]), idKey: string = 'id') {
  const [value, setValue] = useState(initial || [])
  return {
    value,
    setValue,
    push: useCallback(a => setValue(v => [...v, a]), []),
    clear: useCallback(() => setValue(() => []), []),
    removeById: useCallback(id => setValue(arr => arr.filter(v => v && v[idKey] !== id)), []),
    removeIndex: useCallback(
      index =>
        setValue(v => {
          v.splice(index, 1)
          return v
        }),
      [],
    ),
  }
}

2 .可以完全重写自己的工具函数了

你可能感兴趣的:(自定义Hook-组件状态)