美文网首页
自定义Hook-组件状态

自定义Hook-组件状态

作者: skoll | 来源:发表于2020-06-23 21:20 被阅读0次

    强制重新渲染界面

    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 (
            <div ref={domref} onClick={handleClick}>
                {/* width{width} */}
                click-{num}
            </div>
        )
    

    同步到本地存储

    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<T>(props: T) {
      const ref = useRef<T>(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 (
            <>
                <div  onClick={handleClick}>
                    {isOnline}-{num}
    //布尔值是不能直接这样显示出来的,必须要像下面一样
                </div>
                <div onClick={handleRemove}>
                    remove{isOnline?'true':'false'}
                </div>
            </>
            
        )
    

    useArray

    1 .其实就是把python那些方法写成是js的语法
    function useArray<T>(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-组件状态

          本文链接:https://www.haomeiwen.com/subject/ruchfktx.html