createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步相关的知识,希望对你有一定的参考价值。

useRef简单的使用

const usernameUseRef = useRef()
  <input type="text" ref=usernameRef />
     <button
       onClick=() => 
         console.log(usernameRef.current.value)
       
     >

createRef和useRef区别

  • createRef 它可以用在类组件和函数组件中,声明式不能给初始值
  • const usernameCreateRef = createRef()
  • useRef 它只能使用在函数组件中,useRef它可以在声明时给初始值,但一般为null
  • const usernameUseRef = useRef(null)
  • createRef每次重新渲染时都会创建一个ref对象,组件被重新渲染时它也会重新创建,但是因为类组件中它有生命周期,我可以在构造函数中创建这个ref,也就会执行一次。
  • useRef第1次渲染时创建一个对象之后,再新渲染时,如果发现这个对象已经存在过不会再创建,它的性能更好一些,在函数组件中推荐使用useRef


测试:验证;

import React,  createRef, useRef, useEffect, useState  from 'react';

const App = () => 
    const usernameCreateRef = createRef();
    const usernameuseRef = useRef();

    const [value, setvalue] = useState(100)
    if (!usernameCreateRef.current) 
        usernameCreateRef.current = value;
    
    if (!usernameuseRef.current) 
        usernameuseRef.current = value;
    

    return (
        <div>

            <hr />
            <h1>
                createRef:usernameCreateRef.current
            </h1>
            <h1>
                useRef:usernameuseRef.current
            </h1>
            <hr />
            <h1>

            </h1>
            <button onClick=
                () => 
                    setvalue(v => v + 1)
                
            >++++</button>
        </div>
    );


export default App;

forwardRef完成类组件的绑定

  • 如果ref对象绑定在自定义类组件中,则得到当前自定义类组件的实例,从而可以实现组件通信
  • 如果ref直接绑定在自定义函数组件中,则不行,因为函数组件没有实例,所以会报错
  • 函数组件如果你需要绑定ref,则需要通过它提供的一个顶层api方法来增强函数组件从而实现函数组件也可以绑定ref对象 React.forwardRef
  • 直接使用ref的话就会报错


    通过这个forwardRef来包裹一下这个子组件就行。
    就可以ref了
    ,具体还得往下看。

import React,  useRef,forwardRef  from 'react';

const Child = forwardRef((props,_ref) => 

    return (
        <div>
            <h1 ref=_ref>子组件</h1>
        </div>
    );
)

const App = () => 
    const ref = useRef();
    return (
        <div>
            <Child ref=ref/>
            <button onClick=e=>
                console.log(ref.current);
            >@@@@@</button>
        </div>
    );

export default App;

当然通过这个useref可以初始化的特性,ref也可以完成对组件的传值。

 const ref = useRef(100);
const App = () => 
    const ref = useRef(100);
    return (
        <div>
            <Child ref=ref/>
            <button onClick=e=>
                ref.current++
                console.log(ref.current);
            >@@@@@</button>
        </div>
    );

export default App;


useImperativeHandle映射对象

useImperativeHandle 集合useRef和forwardRef 方法来模拟给函数组件绑定ref对象来得到子组件中对外暴露出来的方法或数据

useImperativeHandle(_ref,()=>
    return 
        value,
        changevalue,
        childref
    
)
  • 参数1:就是父组件传过来的ref对象
  • 参数2:回调函数,返回一个对象,穿透给父组件的数据
import React,  useRef,forwardRef, useState ,useImperativeHandle from 'react';

const Child = forwardRef((props,_ref) => 
    let [value,setValue] = useState();
    const changevalue = (newvalue)=>
        setValue(newvalue)
    
    const childref = useRef()
    useImperativeHandle(_ref,()=>
        return 
            value,
            changevalue,
            childref
        
    )

    return (
        <div>
            <h1>子组件</h1>
            <input type="text" name="" id="" ref=childref value="123s"/>
            <h2>value</h2>
        </div>
    );
)

const App = () => 
    const ref = useRef(100);
    return (
        <div>
            <Child ref=ref/>
            <hr />
            <button onClick=e=>
            //    获取到返回来的映射对象,操作子组件的内容
            console.log(ref.current);
            ref.current.changevalue("niupeng")
            >@@@@@</button>
        </div>
    );

export default App;


useLayouEffect同步

import React,  useLayoutEffect, useEffect  from 'react'

const App = () => 

  // js事件循环中,同步优先于异步

  // 异步
  useEffect(()=>
    console.log('useEffect');
  ,[])

  // 同步  如果你是操作dom来说,建议用它
  useLayoutEffect(()=>
    console.log('useLayoutEffect');
    document.title = '你好react'
  ,[])
 

  return <div>
    <h3>App组件</h3>
  </div>


export default App

以上是关于createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步的主要内容,如果未能解决你的问题,请参考以下文章

我应该使用 createRef 还是 useRef,为啥?

React.JS Ref 中的 Ref 错误 - createRef、useRef 和 using Refs

使用 useRef 或 createRef

使用 useRef 或 createRef 而不是 inline ref 有啥优势?

[react] 请说说什么是useRef?

useRef 保存引用值和useImperativeHandle 透传 Ref