美文网首页
自定义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-组件状态

    强制重新渲染界面 1 .代码 2 .使用 获取dom属性 同步到本地存储 获取上一次的props,state 获取...

  • 小程序-自定义组件 ID属性笔记

    在自定义组件的时候,组件内包含了其他自定义组件:如课程列表组件,被状态组件包含(关于状态组件主要是指:加载中,没有...

  • React个人整理

    React基础 自定义新组件 props和propTypes 带状态的文本框组件 从外部访问组件(谨慎使用) 中途...

  • StatefulWidget和StatelessWidget

    StatefulWidget 有状态组件 在 Flutter 中自定义组件其实就是一个类,这个类需要继承 Stat...

  • 自定义组件

    创建自定义组件 使用自定义组件

  • vuepress 中使用vuex this.$store und

    【问题描述】vuepress 搭建的文档,功能越来越复杂,涉及到多组件间传递状态,包括父组件向自定义组件及用户可以...

  • 微信小程序-自定义组件

    一、自定义组件介绍 微信小程序提供了自定义组件扩展机制,允许我们使用自定义组件的方式来构建页面。 自定义组件可以使...

  • vue 自定义组件(一)全局、局部组件

    vue自定义组件分为局部组件和全局组件 全局组件 全局组件格式template 是模板props 是自定义组件用到...

  • vue2.0组件间传值的方法汇总

    1、组件间的传值 1.1 父组件向子组件传值 子组件自定义一个属性 父组件通过自定义属性绑定值 子组件调用自定义属...

  • 调用自定义组件中的方法

    创建自定义组件 .json .js 页面中引入自定义组件 .json .xml 页面中调用自定义组件的方法 .js

网友评论

      本文标题:自定义Hook-组件状态

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