IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React—在高阶组件中转发 Refs -> 正文阅读

[JavaScript知识库]React—在高阶组件中转发 Refs

1 高阶组件概念

https://react.docschina.org/docs/higher-order-components.html.

2 Refs概念

https://react.docschina.org/docs/refs-and-the-dom.html.

3 高阶组件中转发Refs

结合官方文档给出的代码https://react.docschina.org/docs/forwarding-refs.html.我们来分析一下。
首先给出一个高阶组件logProps

import React from 'react'
function logProps(WrappedComponent) {
  const WrappedComponentName=WrappedComponent.displayName ||  WrappedComponent.name
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log(WrappedComponentName+'->old props:', prevProps);
      console.log(WrappedComponentName+'->new props:', this.props);
    }
    render() {
      // const{fowardedRef,...React}
      return <WrappedComponent {...this.props} />;
    }
  }
  return LogProps;
}
export default logProps

然后是FancyButton组件

import React from 'react'
import logProps from './logProps'
class FancyButton extends React.Component {
  sayHi(){
    alert("Hello React")
  }
  render(){
    return <button onClick={this.props.onClick}>FancyButton:{this.props.title}</button>
  }
}
// 我们导出 LogProps,而不是 FancyButton。
// 虽然它也会渲染一个 FancyButton。
export default logProps(FancyButton);

我们在APP.js文件中创造Ref对象,然后检查Ref的值,这里便会发现文档中提到的的问题:

"refs 将不会透传下去。这是因为 ref 不是 prop 属性。就像 key 一样,其被 React 进行了特殊处理。如果你对 HOC 添加 ref,该 ref 将引用最外层的容器组件,而不是被包裹的组件。"

class App extends React.Component{
  constructor(){
    super()
    this.state={
      title:"ABC"
    }
    this.fancyButtonRef= React.createRef()
  }
  handleClickFancyButton=()=>{
    this.setState({
      title:123
    })
    //注意:此处打印出来的Ref是logProps组件,而不是我们想要的FancyButton组件
    console.log("this.fancyButtonRef->",this.fancyButtonRef)
  }
  render(){
    return (
      <div className="App">
        <FancyButton title={this.state.title} 
                     onClick={this.handleClickFancyButton}
                     ref={this.fancyButtonRef}/>
      </div>
    );
  }
}

于是官方文档修改了高阶组件logProps部分代码,如下:

...
  render() {
      const {forwardedRef, ...rest} = this.props;
      // 将自定义的 prop 属性 “forwardedRef” 定义为 ref
      return <WrappedComponent ref={forwardedRef} {...this.props} />;
    }
 // 注意 React.forwardRef 回调的第二个参数 “ref”。
  // 我们可以将其作为常规 prop 属性传递给 LogProps,例如 “forwardedRef”
  // 然后它就可以被挂载到被 LogProps 包裹的子组件上。
  return React.forwardRef((props, ref) => {
    return <LogProps {...props} forwardedRef={ref} />;
  });

4代码背后的数据流程

读到这我已经开始不理解了,查阅了相关资料后,有了如下的理解:
(1)最外层(APP.js)传入自定义的Ref对象

 <FancyButton title=ref={this.fancyButtonRef}/>

(2)logProps组件中通过自带函数拿到Ref值,拿到Ref值后对logProps组件重新绑定,此时拥有Ref对象的属性叫做forwardedRef

  function forwardedRef(props,ref){
    return <LogProps {...props} 
    forwardedRef={ref} />;
  }

(3)重新绑定过后,便来到真实包装的组件,本例是logProps组件中的真实包装组件WrappedComponent。然后把ref的值重新传进去(相当于A传B,B传C,数据都是一样的)

 render() {
      const {forwardedRef, ...rest} = this.props;
      return <WrappedComponent ref={forwardedRef} {...this.props} />;

(4)拿到了包裹组件后,我们就可以在最外层直接调用包裹组件里面的方法,本例中是sayHi()

APP.js

handleClickFancyButton=()=>{
    this.setState({
      title:123
    })
    this.fancyButtonRef.current.sayHi()
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-08 11:13:05  更:2021-08-08 11:16:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 8:38:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码