react 高阶组件

react 高阶组件

高阶函数(Higher-order funciton)

简称:HOC,至少满足下面一个条件

  • 接受一个或者多个函数作为输入
  • 输出一个函数
	const EnhancedComponent = highOrderComponent(WrappedComponent);

该函数接收一个组件WrappedComponent作为参数,返回加工过的新组建EnhancedComponent.
本质上是一个装饰者模式

基本模版
	import React, { Component } from 'react';
	export default (WrappedComponent) => {
		return class EnhancedComponent extends Component {
	 	// do something
			 render() {
			 	return <WrappedComponent />;
			 }
	 	}
	}

通过对传入的原始组件WrappedComponent,做一些你想要的操作(比如:操作props,提取state,给原始组件包裹其他元素),从而加工出想要的组件EnhancedComponent.

把通用的逻辑放在高阶组件中,对组件实现一致的处理,从而实现代码的复用

遵循约定:

  • props保持一致
  • 不鞥在函数式(无状态)组件上使用ref属性,因为他没有实例
  • 不要以任何方式改变原始组件WrappedComponent
  • 透传不相关props属性给被包裹的组件WrappedComponent
  • 不要在render() 方法中使用高阶组件
  • 使用compose组合高阶组件

注意:高阶组件可以传递所有的props,但是不能传递ref
如果想一个高阶组件添加refs引用,那么ref指向的是最外层容器组件实例的,而不是被包裹的组件,如果需要传递refs的话,则使用React.forwardRef

如下:

	function withLogging(WrappedComponent) {
		 class Enhance extends WrappedComponent {
			 componentWillReceiveProps() {
				 console.log('Current props', this.props);
				 console.log('Next props', nextProps);
			 }
			 render() {
				 const {forwardedRef, ...rest} = this.props;
				 // forwardedRef ref
				 return <WrappedComponent {...rest} ref={forwardedRef} />;
			 }
		 };
			 // React.forwardRef props ref 
			 // ref React.forwardRef 
			 function forwardRef(props, ref) {
			 	return <Enhance {...props} forwardRef={ref} />
			 }
			 return React.forwardRef(forwardRef);
		}
	const EnhancedComponent = withLogging(SomeComponent);
使用场景

如:权限控制,日志记录,数据校验,异常处理,统计上报等…

举例,存在一个组件,需要从缓存中获取数据,然后渲染。

	import React, { Component } from 'react'
	class MyComponent extends Component {
		 componentWillMount() {
		 	let data = localStorage.getItem('data');
		 	this.setState({data});
		 }
 
		 render() {
		 	return <div>{this.state.data}</div>
		 }
	}

高阶组件改写:

	import React, { Component } from 'react'
	function withPersistentData(WrappedComponent) {
	
		 return class extends Component {
			 componentWillMount() {
				 let data = localStorage.getItem('data');
				 this.setState({data});
		 	 }
	 
			 render() {
			 // {...this.props} WrappedComponent
			 	return <WrappedComponent data={this.state.data} {...this.props} />
			 }
		 }
	}
	
	class MyComponent2 extends Component { 
		 render() {
		 	return <div>{this.props.data}</div>
		 }
	}
	const MyComponentWithPersistentData = withPersistentData(MyComponent2)

比如组件渲染性能监控,如下:

	class Home extends React.Component {
		 render() {
		 	return (<h1>Hello World.</h1>);
		 }
	}

	function withTiming(WrappedComponent) {
		return class extends WrappedComponent {
			 constructor(props) {
				 super(props);
				 this.start = 0;
				 this.end = 0;
			 }
			 
			 componentWillMount() {
			 	super.componentWillMount && super.componentWillMount();
			 	this.start = Date.now();
			 }
			 
			 componentDidMount() {
			 	super.componentDidMount && super.componentDidMount();
			 	this.end = Date.now();
			 	console.log(`${WrappedComponent.name} ${this.end- this.start} ms`);
			 }
			 
			 render() {
			 	return super.render();
			 }
		};
	}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值