Ref从入门到入土

首先做个对比:Ref从入门到入土_第1张图片

 功能一:引用一个值做持久化记忆

场景:清除定时器

import { useRef } from "react"
import { useState } from "react"
// ref:1.引用一个值 做持久化记忆 
// let num = useRef(1)
// console.log(num.current++);
// 避免渲染ref的值,其值改变时不会触发更新(区别于state)
const App = () => {

    const [count, setCount] = useState(0)

    // let timer = null
    // const handleClick = () => {
    //     setCount(count + 1)

    //     // 不能有效清除定时器,因为每次只能清除当前作用域的timer,但是每次setState都会产生新的作用域,则多次点击会导致定时器累加
    //     clearInterval(timer)
    //     timer = setInterval(() => {
    //         console.log('setInterval...');
    //     }, 1000);
    // }

    let timer = useRef(null)
    const handleClick = () => {
        setCount(count + 1)

        // ref具有记忆性,可以拿到第一次产生的timer,然后清除,保证每次只有一个定时器在
        clearInterval(timer.current)
        timer.current = setInterval(() => {
            console.log('setInterval...');
        }, 1000);
    }


    return (<>
        hello hook
        
        
count:{count}, ) } export default App

 功能二:在react中操作dom(避免原生写法

const App = () => {

    const myRef = useRef(null)
    const fun = () => {
        console.log(myRef.current.innerHTML);
        myRef.current.style.color = 'skyblue'
    }
    const list = [
        { id: 1, text: 'aaa' },
        { id: 2, text: 'bbb' },
        { id: 3, text: 'ccc' }
    ]
    return (
        <>
            
            
div
{/* 循环中操作ref可以使用回调写法 */}
    { list.map((item) => { return
  • { mf.style.background = 'pink' }}>{item.text}
  • }) }
) } export default App

注意:当给子组件添加ref时,需要对其 forwardRef 转发,用于向父组件公开其dom


const Zi = forwardRef(function myInput(props, refs) {
    return 
})

const App = () => {
    const myref = useRef(null)
    const fn = () => {
        myref.current.focus()
        myref.current.style.background = 'skyblue'
    }
    return (<>
        hello App
        
        
    )



}

export default App

进阶:useImperativeHandle用于为组件自定义暴露方法

import { useRef, forwardRef, useImperativeHandle } from "react"

const Zi = forwardRef(function myInput(props, refs) {
    const inputRef = useRef(null)
    useImperativeHandle(refs, () => {
        return {
            myFocus() {
                inputRef.current.focus()
            },
            focusAndStyle() {
                inputRef.current.focus()
                inputRef.current.style.background = 'red'
            }
        }
    })
    return (
        
    )
})
const App = () => {
    const myref = useRef(null)
    const fn = () => {
        myref.current.myFocus()
        myref.current.focusAndStyle()
        // 以下会报错 myref.current.focus is not a function,因为只有以上俩方法暴露了
        // myref.current.focus()  
    }
    return (<>
        hello App
        
        
    )

}

export default App

你可能感兴趣的:(React,javascript,前端,react.js)