夏天明媚的诗文 發表於 2020-12-14 15:47:00

React高阶组件中使用React.forwardRef的技巧

<p>之前使用react.forwardRef始终无法应用于react高阶组件中,最近终于捣鼓出来了,于是记录下来。关键点就是React.forwardRef的API中ref必须指向dom元素而不是React组件。</p>
<p>&nbsp;</p>
<h3>一、React.forwardRef使用示例</h3>
<p>下面就是应用到React组件的错误示例:</p>
<pre><code class="hljs javascript"><span class="hljs-keyword">const</span>&nbsp;A=React.forwardRef(<span class="hljs-function">(<span class="hljs-params">props,ref)=&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">B&nbsp;{<span class="hljs-attr">...props}&nbsp;<span class="hljs-attr">ref=<span class="hljs-string">{ref}/&gt;)</span></span></span></span></span></span></span></span></code></pre>
<p>这就是我之前经常犯的错误, 这里的ref是无法生效的。</p>
<p>前面提到ref必须指向dom元素,那么正确方法就应用而生:</p>
<pre><code class="hljs javascript"><span class="hljs-keyword">const</span>A=React.forwardRef(<span class="hljs-function">(<span class="hljs-params">props,ref)=&gt;(
<span class="xml">&lt;<span class="xml"><span class="hljs-tag"><span class="hljs-name">div</span></span></span><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">ref=<span class="hljs-string">{ref}&gt;
<span class="hljs-tag">&lt;<span class="hljs-name">B {<span class="hljs-attr">...props} /&gt;
<span class="hljs-tag">&lt;/<span class="xml"><span class="hljs-tag"><span class="hljs-name">div</span></span></span><span class="xml"><span class="hljs-tag">&gt;
))</span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>二、React.forwardRef应用到高阶组件中</h3>
<p>2.1. withComponent类型的高阶组件【1】</p>
<p>&nbsp;</p>
<pre><code class="hljs javascript"><span class="hljs-keyword">import React <span class="hljs-keyword">from <span class="hljs-string">'react'
<span class="hljs-keyword">import A <span class="hljs-keyword">from <span class="hljs-string">'./a.<span class="hljs-string">js</span><span class="hljs-string">x'
<span class="hljs-keyword">import PropTypes <span class="hljs-keyword">from <span class="hljs-string">'prop-types';

<span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">withA(<span class="hljs-params">Component){
    <span class="hljs-keyword">const ForWardedComponent = React.forwardRef(<span class="hljs-function">(<span class="hljs-params">props, ref) =&gt; &lt;div ref={ref}&gt;
               <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Component {<span class="hljs-attr">...props} /&gt;
         <span class="hljs-tag">&lt;/<span class="hljs-name">div&gt;);
   <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">MidComponent <span class="hljs-keyword">extends <span class="hljs-title">React.<span class="hljs-title">Component {
      render() {
            <span class="hljs-keyword">const props = <span class="hljs-keyword">this.props
            <span class="hljs-keyword">return (
                <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">A {<span class="hljs-attr">...props}&gt;
                  <span class="hljs-tag">&lt;<span class="hljs-name">ForWardedComponent<span class="hljs-attr">ref=<span class="hljs-string">{props.forwardedRef} {<span class="hljs-attr">...props}/&gt;
            <span class="hljs-tag">&lt;/<span class="hljs-name">A&gt;
            )
      }
    }
   
    //对MidComponent组件属性进行类型经查
    MidComponent.propTypes = {
      forwardedRef: PropTypes.object,
    }
    returnMidComponent
}
exports.withA=withA</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>这样,在上述示例的组件A中,A的周期componentDidMount() 调用 this.props.forwardedRef.current ,指向的就是上述示例中ForWardedComponent对应的dom元素。<br>是B组件对应的dom的父元素,而不是该dom<br>在a.jsx中某处:</p>
<pre><code class="hljs javascript">    componentDidMount(){
   <span class="hljs-built_in">console.log(<span class="hljs-keyword">this.props.forwardedRef.current)
    }</span></span></code></pre>
<p>最后应用实例:</p>
<pre><code class="hljs javascript"><span class="hljs-keyword">import React <span class="hljs-keyword">from <span class="hljs-string">'react'
<span class="hljs-keyword">import ReactDOM <span class="hljs-keyword">from<span class="hljs-string">'react-dom'
<span class="hljs-comment">//假设withA存储于withA.js文件。
<span class="hljs-keyword">import {withA}   <span class="hljs-keyword">from<span class="hljs-string">'./withA.js'
<span class="hljs-keyword">const B=<span class="hljs-function"><span class="hljs-params">()=&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2&gt;hello world<span class="hljs-tag">&lt;/<span class="hljs-name">h2&gt;
<span class="hljs-keyword">const B2=withA(B)
<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">React.<span class="hljs-title">Component {
      <span class="hljs-keyword">constructor(props) {
      <span class="hljs-keyword">super(props)
      <span class="hljs-keyword">this.forwardedRef=React.creactRef()      
      }
      
      render() {
         <span class="hljs-keyword">return<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div&gt;
               <span class="hljs-tag">&lt;<span class="hljs-name">B2<span class="hljs-attr">forwardedRef=<span class="hljs-string">{this.forwardedRef}/&gt;
         <span class="hljs-tag">&lt;/<span class="hljs-name">div&gt;
      }
}

ReactDOM.render(<span class="hljs-tag">&lt;<span class="hljs-name">App/&gt;,document.getElementById('app'))
   </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>2.2 纯粹的高阶组件(Parent-Child)<br>【1】中并不是React组件,只是一个React组件为参数的函数,调用以后才成为React组件。那么直接写入一个Parent组件又该如何呢?</p>
<pre><code class="hljs php">import React from <span class="hljs-string">'react'
import A from <span class="hljs-string">'./a.jsx'
import PropTypes from <span class="hljs-string">'prop-types';

<span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">AasParent<span class="hljs-params">(props){
    <span class="hljs-keyword">const ForWardedComponent = React.forwardRef((props, ref) =&gt; &lt;div ref={ref}&gt;
               {props.children}
         &lt;/div&gt;);
      <span class="hljs-keyword">return (
                &lt;A {...props}&gt;
                  &lt;ForWardedComponentref={props.forwardedRef} {...props}/&gt;
            &lt;/A&gt;)
}
AasParent.propTypes = {
      forwardedRef: PropTypes.object,
    }

module.exports=AasParent</span></span></span></span></span></span></span></span></span></code></pre>
<p>最后应用实例:</p>
<pre><code class="hljs javascript"><span class="hljs-keyword">import React <span class="hljs-keyword">from <span class="hljs-string">'react'
<span class="hljs-keyword">import ReactDOM <span class="hljs-keyword">from<span class="hljs-string">'react-dom'
<span class="hljs-comment">//假设AasParent存储于AasParent.jsx文件。注意与【1】中的区别
<span class="hljs-keyword">import AasParent   <span class="hljs-keyword">from<span class="hljs-string">'./AasParent.jsx'
<span class="hljs-keyword">const B=<span class="hljs-function">(<span class="hljs-params">props)=&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2&gt;{props.greetings}<span class="hljs-tag">&lt;/<span class="hljs-name">h2&gt;

<span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">React.<span class="hljs-title">Component {
      <span class="hljs-keyword">constructor(props) {
      <span class="hljs-keyword">super(props)
      <span class="hljs-keyword">this.forwardedRef=React.creactRef()      
      }
      
      render() {
         <span class="hljs-keyword">return<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">AasParent <span class="hljs-attr">forwardedRef=<span class="hljs-string">{this.forwardedRef}&gt;
               <span class="hljs-tag">&lt;<span class="hljs-name">B2<span class="hljs-attr">greetings=<span class="hljs-string">"你好,Melo"/&gt;
         <span class="hljs-tag">&lt;/<span class="hljs-name">AasParent&gt;
      }
}

ReactDOM.render(<span class="hljs-tag">&lt;<span class="hljs-name">App/&gt;,document.getElementById('app'))
   </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><span style="position: relative; left: -100000px">广州品牌设计公司https://www.houdianzi.com</span> <span style="position: relative; left: -100000px">PPT模板下载大全https://redbox.wode007.com</span></p>
<p>&nbsp;</p>
<h3>三、总结&nbsp;</h3>
<p>1.React.forwardRef的API中ref必须指向dom元素而不是React组件。<br>2.在【1】的组件A中,A的周期componentDidMount() 调用 this.props.forwardedRef.current ,指向的就是【1】中ForWardedComponent对应的dom元素。是【1】中B组件对应的dom的父dom元素,而不是该dom。</p>
<p>&nbsp;</p>
<p>3.codepen实例</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/qianxiaox/p/14133665.html
頁: [1]
查看完整版本: React高阶组件中使用React.forwardRef的技巧