什么是高阶组件?

高阶组件就是接受一个组件作为参数并返回一个新组件的函数。这里需要注意高阶组件是一个函数,并不是组件,这一点一定要注意。同时这里强调一点高阶组件本身并不是 React API。它只是一种模式,这种模式是由React自身的组合性质必然产生的。更加通俗的讲,高阶组件通过包裹(wrapped)被传入的React组件,经过一系列处理,最终返回一个相对增强(enhanced)的 React 组件,供其他组件调用。

react中获取的ref是什么?

  • 如果ref写在组件上,那么获取的是 组件的实例对象;
  • 如果ref写在组件内的标签上(div,span等),获取的相应的DOM节点那么可知本文中获取的高阶组件的ref所指的是组件的实例对象即 子组件的this

获取方式:

@withRouter
export default class childComponent extends Component {
constructor(props) {
super(props);
this.state = {};
const { getInstance } = props;
if (typeof getInstance === 'function') {
getInstance(this); // 在这里把this暴露给`parentComponent`
}
}
render() {
return (<div>this is childComponent</div>)
}
}
@withRouter
export default class parentComponent extends Component {
constructor(props) {
super(props);
this.state = {};
}
render () {
return (
<childComponent
ref={(withRouter) => { this.childCpWrapper = withRouter; }} // 这里获取的是`withRouter`组件,一般没啥用,这里写出来只是为了对比
getInstance={(childCp) => { this.childCp = childCp; }} // 这里通过`getInstance`传一个回调函数接收`childComponent`实例即可
/>
);
}
}

下面将上面的方法优化一下,单独写一个类来获取

// 只做一件事,把`WrappedComponent`回传个`getInstance`(如果有的话)
export default (WrappedComponent) => {
return class withRef extends Component {
static displayName = `withRef(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
render() {
// 这里重新定义一个props的原因是:
// 你直接去修改this.props.ref在react开发模式下会报错,不允许你去修改
const props = {
...this.props,
};
const { getInstance } = props;
if (typeof getInstance === 'function') {
// 在这里把getInstance赋值给ref,
// 传给`WrappedComponent`,这样就getInstance能获取到`WrappedComponent`实例
props.ref = getInstance;
}
return (
<WrappedComponent {...props} />
);
}
};
}; // 如何使用?
@withRouter
@withRef // 这样使用是不是方便多了,注意:这句必须写在最接近`childComponent`的地方
export default class childComponent extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (<div>this is childComponent</div>)
}
}
@withRouter
export default class parentComponent extends Component {
constructor(props) {
super(props);
this.state = {};
}
render () {
return (
<childComponent
// 这里获取的是`withRouter`组件,一般没啥用,这里写出来只是为了对比
ref={(withRouter) => { this.childCpWrapper = withRouter; }}
// 这里通过`getInstance`传一个回调函数接收`childComponent`实例即可
getInstance={(childCp) => { this.childCp = childCp; }}
/>
);
}
}

最新文章

  1. LInux MySQL 端口验证
  2. CocoaPods的版本升级
  3. Web 前端开发人员和设计师必读文章推荐【系列二十八】
  4. 读取XML文件的节点内的内容
  5. imx6 lvds 代码分析
  6. ViewPager 基本方式加载view
  7. sed程序
  8. ECSHOP在线手册布局参考图--商品详情页 goods.dwt
  9. 亲试,Windows平台上使用Qt5.2.1编写Android
  10. 基于 websocket 实现的 im 实时通讯案例
  11. My MES思路图
  12. LInux 些许知识
  13. google gcr.io、k8s.gcr.io 国内镜像
  14. 巧用CurrentThread.Name来统一标识日志记录
  15. 学JS的心路历程-函式(六)其余参数及预设参数
  16. 提示 make: 没有什么可以做的为 `all&#39;
  17. .net 取得类的属性、方法、成员及通过属性名取得属性值
  18. [SPOJ-LCS]Longest Common Substring
  19. 如何用git命令行上传本地代码到github
  20. java程序设计基础篇 复习笔记 第四单元

热门文章

  1. Chrome开发者工具详解(四)之Elements、Console、Sources面板
  2. MFC- 网络编程
  3. socket 服务器向指定的客户端发消息
  4. Python numpy数据的保存和读取
  5. linux用户管理(useradd、userdel、usermod、groupadd、groupdel、chage、passwd、chpasswd)
  6. Django【第1篇】:Django之MTV模型
  7. Django【第19篇】:Django之extra
  8. Linux下升级安装Python-3.6.9版本
  9. 【leetcode】1108. Defanging an IP Address
  10. 文件打包压缩——tar