强制重新渲染界面
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 .可以完全重写自己的工具函数了
网友评论