react.forwardref(reactforwardref用法)

lxf2023-04-19 21:54:02
摘要

这篇文章主要介绍了React操作DOM之forwardRef问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

目录
  • React操作DOM之forwardRef
  • React forwardRef使用方法
    • 作用与注意点
    • 父 -> 子 -> 子(Dom)
    • 父 -> 子 -> 子(class)
    • 高阶组件中的特殊情况
  • 总结

    React操作DOM之forwardRef

    React操作DOM有几种方式,传入字符串,传入一个对象(react推荐的方式),传入一个函数,今天就讲一下使用react封装过的高阶组件forwardRef来操作DOM

    首先导入

    import React, { PureComponent,createRef,forwardRef } from 'react'

    然后const一个函数组件,将它作为App的子组件

    const Profile = forwardRef(function (props,ref){
      return <h2 ref={ref}>Profile</h2>
    })
    

    定义App组件

    export default class App extends PureComponent {
      constructor(props){
        super(props);
        this.profileRef = createRef()
      }
      render() {
        return (
          <div>
            <Profile ref={this.profileRef} name={'lsh'}/>
            <button onClick={e=>this.printRef()}>点击</button>
          </div>
        )
      }
      printRef(){
        console.log(this.profileRef.current)
      }
    }
    

    当我们点击按钮时候

    react.forwardref(reactforwardref用法)

    用这个的好处是什么?因为我们之前操作dom,函数式组件是不行的,因为它没有实例,用这个高阶组件就能完美解决这个问题

    React forwardRef使用方法

    作用与注意点

    • 传递ref,把自身的ref绑定到其他地方(e.g. 你把文件交给总裁秘书,总裁秘书把文件交给总裁)
    • ref 和 key 有点特殊,不会作为props参数向下传递,this.props拿不到ref对象
    • 函数组件是没有实例的,可以用useImperativeHandle实现部分功能
    • 高阶组件需做特殊处理

    react.forwardref(reactforwardref用法)

    父 -> 子 -> 子(Dom)

    react.forwardref(reactforwardref用法)

    import React, { useRef } from 'react';
    import Content from './content';
    
    const Home = () => {
      // 创建一个Ref对象
      const connectRef = useRef(null);
    
      const handleFoucus = () => {
        const _ref = connectRef.current;
        _ref.focus();
      };
    
      return (
        <div>
            <button onClick={() => handleFoucus()}>
              使用子组件中DOM元素的方法
            </button>
    
            <Content ref={connectRef} />
        </div>
      );
    };
    
    export default Home;
    
    import React, { forwardRef } from 'react';
    
    
    const Content = (props, ref) => {
      return (
        <div>
       	  {}
          <input type="passWord" ref={ref} />
        </div>
      )
    };
    
    export default forwardRef(Content);
    

    父 -> 子 -> 子(class)

    react.forwardref(reactforwardref用法)

    import React, { useRef } from 'react';
    import Content from './content';
    
    const Home = () => {
      // 创建一个Ref对象
      const connectRef = useRef(null);
    
      const handleAdd = () => {
        const _ref = connectRef.current;
    
        const { count } = _ref.state;
        _ref.setState({
          count: count + 1
        })
      };
    
      return (
        <div>
            <button onClick={() => handleAdd()}>
              使用子组件中class组件的属性和方法
            </button>
    
            <Content ref={connectRef} />
        </div>
      );
    };
    
    export default Home;
    
    import React, { forwardRef } from 'react';
    import Header from './header';
    import Footer from './footer';
    
    
    const Content = (props, ref) => {
      return (
        <div>
          {}
          <Header ref={ref} />  {}
    		
          {}
        </div>
      )
    };
    
    export default forwardRef(Content)
    
    import React from 'react';
    
    export default class Header extends React.Component {
      state = {
        count: 0
      };
    
      render() {
        return (
          <div>
            {this.state.count}
          </div>
        )
      }
    };
    

    高阶组件中的特殊情况

    • 高阶组件本质是函数,参数为组件,返回值是新组件(增强过的组件)
    • 高阶组件会把所有接收到的props,传递给被包装的组件(透传)
    • ref 和 key 类似,不是一个prop,所以不会透传,ref会绑定到外层的高阶组件上
    • 高阶组件可以嵌套多层,e.g. Hoc1(Hoc2(Hoc3(Content)))

    所以为了把ref传递给最里面的组件,有两种方法

    • 在最外层用 forwardRef 对 ref 对象进行处理,ref -> ref -> props.key = ref
    • 不用 ref,用自定义props承载 ref 对象,props.key = ref
    
    

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。