6.1.3.react ref

344 阅读1分钟

1.useRef createRef区别

ref是React提供的用来操纵React组件实例或者DOM元素的接口;
接收一个初始值,返回一个对象,这个对象中只有一个current属性;
组件依赖的props以及state状态发生变更,createRef每次都会返回个新的引用;而useRef不会随着组件的更新而重新创建;

2. 解决react hooks方法获取不到最新的state

import React, {useState, useEffect, useRef} from "react";
import { Button } from "antd"
 
const Demo = () => {
    const numRef = useRef(1)
    const [num, changeNum] = useState(numRef.current)
 
    const setNum = () => {
        numRef.current = num + 1
        changeNum(numRef.current)
        console.log(numRef.current)
    }
 
    return (
      <div>
          <Button onClick={setNum}>点我+1</Button>
          <div>{num}</div>
      </div>
    )
}
 
export default Demo
 

3. 自定义回调获取子组件属性

if (props.onRef && onRef.current) { 
    props.onRef.current.childProp = 'child prop' 
 }

4.useImperativeHandle

父组件:

export default function App() {
  const classRef = useRef();
  const functionRef = useRef();
  return (
    <>
      <MyClass ref={classRef} />
      <MyCounter ref={functionRef} />
    </>
  );
}

class子组件

class MyClass extends React.Component{
    constructor(props){
      super(props)
    }
    increment = ()=>{...}
    render(){
      return <button onClick={this.increment}>+1</button>
    }
}

function子组件,通过useImperativeHandle,否则返回null

function MyCounter(props, ref) {
  const [count, setCount] = useState(0);
  useImperativeHandle(ref, () => ({
    resetCount: resetCount,
  }));
  function resetCount() {
    setCount(0);
  }
  function increment() {
    setCount(count + 1);
  }
  return (
    <div>
      <button onClick={increment}>+1</button>
    </div>
  );
}

5.forwardRef

  • 能够将其接受的 ref 属性转发到其组件树下的另一个组件中
  • 父组件可以拿到孙子组件

使用场景: 在hoc组件使用ref;如有connect、withRouter
父组件代码:

 this.mychild = React.createRef()
 <Mycomponent aa="aa" ref={this.mychild}/>

无ref传递代码:

export default connect(mapstateProps,mapDispatchProps)(withRouter(Mycomponent))

forwardRef 传递ref代码:

export default React.forwardRef((props1,ref)=>{
  class Hoc extends React.Component{
    constructor(props){
      super(props)
      // consle.log(props1,props,ref)
      // prop1是父组件aa参数,props是connect、withRouter传进来的参数
      // 此时ref.current为null
    }
    render(){
      return <Mycomponent {...this.props} ref={ref}/>
    }
  }
  
  var Warpper = connect(mapstateProps,mapDispatchProps)(withRouter(Hoc))
  return <Warpper />
})