React高阶组件中使用React.forwardRef的技巧
<p>之前使用react.forwardRef始终无法应用于react高阶组件中,最近终于捣鼓出来了,于是记录下来。关键点就是React.forwardRef的API中ref必须指向dom元素而不是React组件。</p><p> </p>
<h3>一、React.forwardRef使用示例</h3>
<p>下面就是应用到React组件的错误示例:</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)=><span class="xml"><span class="hljs-tag"><<span class="hljs-name">B {<span class="hljs-attr">...props} <span class="hljs-attr">ref=<span class="hljs-string">{ref}/>)</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)=>(
<span class="xml"><<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}>
<span class="hljs-tag"><<span class="hljs-name">B {<span class="hljs-attr">...props} />
<span class="hljs-tag"></<span class="xml"><span class="hljs-tag"><span class="hljs-name">div</span></span></span><span class="xml"><span class="hljs-tag">>
))</span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p> </p>
<p> </p>
<h3>二、React.forwardRef应用到高阶组件中</h3>
<p>2.1. withComponent类型的高阶组件【1】</p>
<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 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) => <div ref={ref}>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">Component {<span class="hljs-attr">...props} />
<span class="hljs-tag"></<span class="hljs-name">div>);
<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"><<span class="hljs-name">A {<span class="hljs-attr">...props}>
<span class="hljs-tag"><<span class="hljs-name">ForWardedComponent<span class="hljs-attr">ref=<span class="hljs-string">{props.forwardedRef} {<span class="hljs-attr">...props}/>
<span class="hljs-tag"></<span class="hljs-name">A>
)
}
}
//对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">()=><span class="xml"><span class="hljs-tag"><<span class="hljs-name">h2>hello world<span class="hljs-tag"></<span class="hljs-name">h2>
<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"><<span class="hljs-name">div>
<span class="hljs-tag"><<span class="hljs-name">B2<span class="hljs-attr">forwardedRef=<span class="hljs-string">{this.forwardedRef}/>
<span class="hljs-tag"></<span class="hljs-name">div>
}
}
ReactDOM.render(<span class="hljs-tag"><<span class="hljs-name">App/>,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) => <div ref={ref}>
{props.children}
</div>);
<span class="hljs-keyword">return (
<A {...props}>
<ForWardedComponentref={props.forwardedRef} {...props}/>
</A>)
}
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)=><span class="xml"><span class="hljs-tag"><<span class="hljs-name">h2>{props.greetings}<span class="hljs-tag"></<span class="hljs-name">h2>
<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"><<span class="hljs-name">AasParent <span class="hljs-attr">forwardedRef=<span class="hljs-string">{this.forwardedRef}>
<span class="hljs-tag"><<span class="hljs-name">B2<span class="hljs-attr">greetings=<span class="hljs-string">"你好,Melo"/>
<span class="hljs-tag"></<span class="hljs-name">AasParent>
}
}
ReactDOM.render(<span class="hljs-tag"><<span class="hljs-name">App/>,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> </p>
<h3>三、总结 </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> </p>
<p>3.codepen实例</p>
<p> </p><br><br>
来源:https://www.cnblogs.com/qianxiaox/p/14133665.html
頁:
[1]