玉裕 發表於 2019-11-2 15:11:00

React Ref 和 React forwardRef

<ol>
<li>
<h2>用ref来触达dom元素或组件实例</h2>
</li>
<ol>
<li>ref是reference(引用)的简写。</li>
<li>在数据流之外直接操作子孙组件:<ol>
<li>ref属性赋值给Html元素,那么this.ref.current就获取到html元素</li>
<li>ref属性赋值给常规React组件,那么this.ref.current就获取到组件的实例</li>
</ol></li>
<li>不要过度使用:<ol>
<li>有需要直接触达和操作子孙组件实例或者操作子dom元素的情况,这时候应该使用React Ref。</li>
<li>如果属性下传能够解决问题,应该使用声明式的属性传递,而非命令式的ref。</li>
</ol></li>
<li>使用场景:<ol>
<li>用来处理立即执行的动画,(我们知道流畅的动画或对用户动作的即时响应一般需要脱离react数据流,需要直接操作DOM节点(D3.js)或者node节点(cocos.js))。</li>
<li>用来处理非受控组件(比如没有用onChange检测数值的input元素)的焦点,什么是受控/非受控组件参考文章。</li>
<li>用来与第三方库对接,我知道的有d3 或者 cocos,因为第三方库需要获取dom或者节点。</li>
</ol></li>
</ol>
<li>
<h2>React.forwardRef((props,ref)=&gt;&lt;Compnent/&gt;)</h2>
<ol>
<li>简而言之就是自动透传引用(Ref),能让组件接收传过来的ref, 向下(或者说向前)传递Ref。
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">const FancyButton = React.forwardRef((props, ref) =&gt; (
&lt;button ref={ref} className="FancyButton"&gt;
    {props.children}
&lt;/button&gt;
));

// You can now get a ref directly to the DOM button:<br>// 现在你可以获取DOM按钮的引用
const ref = React.createRef();
&lt;FancyButton ref={ref}&gt;Click me!&lt;/FancyButton&gt;;  </pre>
</div>
</li>
<li>
<p>上述代码的解释:</p>
<ol>
<li>首先创建了一个ref, 这个ref的目的就是抓到子组件中的&lt;button&gt;DOM节点</li>
<li>通过组件jsx属性把ref传给子组件&lt;FancyButton&gt;,这一行
<pre class="brush:javascript;gutter:true;">&lt;FancyButton ref={ref}&gt;Click me!&lt;/FancyButton&gt;; </pre>
</li>
<li>FancyButton组件通过React.forwardRef透传props和ref,这里ref才是我们要注意的点。</li>
<li>forwardRef参数是一个函数,这个函数有一个ref参数,将其赋给子组件&lt;button&gt; 的ref属性</li>
<li>当ref关联上之后,这个ref.current将指向&lt;button&gt;的DOM节点。</li>
</ol></li>
</ol></li>
<li>
<h2>React.forwardRef((props, ref)=&gt;&lt;Componnet&gt;)在高阶组件中的使用:</h2>
<ol>
<li>比如我们写一个打印前后属性的高阶组件logProps,这个高阶组件能够透传ref
<div class="cnblogs_code">
<pre> 1 function<span> logProps(Component) {
2 <span>class LogProps extends React.Component {
3 <span>    componentDidUpdate(prevProps) {
4       console.log('old props:'<span>, prevProps);
5       console.log('new props:', this<span>.props);
6 <span>    }
7
8 <span>    render() {
9       const {forwardedRef, ...rest} = this<span>.props;
11       // 把常规属性"forwardedRef"作为ref赋值给传过来的Component组件
12       return &lt;Component ref={forwardedRef} {...rest} /&gt;;
13 <span>    }
14 <span>}
15
16   // 注意React.forwardRef提供的第二个参数ref.
17   // 我们可以把ref作为一个常规属性"forwardedRef"传给LogProps这个组件
18   // 就可以跟实例绑定.
19   return React.forwardRef((props, ref) =&gt;<span> {
20   return &lt;LogProps {...props} forwardedRef={ref} /&gt;;
21 <span>});
22 }</span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p>&nbsp;</p>
</li>
</ol></li>
</ol>

</div>
<div id="MySignature" role="contentinfo">
    晚来一阵风兼雨<br><br>
来源:https://www.cnblogs.com/dejunwang/p/11782484.html
頁: [1]
查看完整版本: React Ref 和 React forwardRef