当前位置: 移动技术网 > IT编程>开发语言>JavaScript > React进阶学习之组件的解耦之道

React进阶学习之组件的解耦之道

2017年12月12日  | 移动技术网IT编程  | 我要评论

前言

众所周知,react中的组件非常的灵活可扩展,不过随着业务复杂度的增加和许多外部工具库的引入,组件往往也会显得浮肿,接下来我们就一起来看看常见的几种,遵循单一职责原则的,组件分割与解耦的方法,话不多说了,来一起看看详细的介绍:

一、分割 render 函数

当一个组件渲染的内容较多时,有一个快速并且通用的方法是创建sub-render函数来简化原来庞大的 render

class panel extends react.component {
 renderheading() {
 // ...
 }

 renderbody() {
 // ...
 }

 render() {
 return (
 <div>
 {this.renderheading()}
 {this.renderbody()}
 </div>
 );
 }
}

为了再次简化sub-render函数,我们还可以采用functional components写法,这种方式生成了更小的处理单元,且更有利于测试

const panelheader = (props) => (
 // ...
);

const panelbody = (props) => (
 // ...
);

class panel extends react.component {
 render() {
 return (
 <div>
 // nice and explicit about which props are used
 <panelheader title={this.props.title}/>
 <panelbody content={this.props.content}/>
 </div>
 );
 }
}

二、用 props 传递元素

如果一个组件的状态或配置较多,我们可以运用props传递元素而不仅是数据,比如再声明一个组件,使其中的父组件只专注于配置

class commenttemplate extends react.component {
 static proptypes = {
 // declare slots as type node
 metadata: proptypes.node,
 actions: proptypes.node,
 };

 render() {
 return (
 <div>
 <commentheading>
  <avatar user={...}/>

  // slot for metadata
  <span>{this.props.metadata}</span>

 </commentheading>
 <commentbody/>
 <commentfooter>
  <timestamp time={...}/>

  // slot for actions
  <span>{this.props.actions}</span>

 </commentfooter>
 </div>
 );
 }
}

父组件

class comment extends react.component {
 render() {
 const metadata = this.props.publishtime ?
 <publishtime time={this.props.publishtime} /> :
 <span>saving...</span>;

 const actions = [];
 if (this.props.issignedin) {
 actions.push(<likeaction />);
 actions.push(<replyaction />);
 }
 if (this.props.isauthor) {
 actions.push(<deleteaction />);
 }

 return <commenttemplate metadata={metadata} actions={actions} />;
 }
}

三、使用高阶组件

实现点击某组件的超链接,发送该组件的 id,我们大多的解决方法可能如下

class document extends react.component {
 componentdidmount() {
 reactdom.finddomnode(this).addeventlistener('click', this.onclick);
 }

 componentwillunmount() {
 reactdom.finddomnode(this).removeeventlistener('click', this.onclick);
 }

 onclick = (e) => {
 if (e.target.tagname === 'a') { // naive check for <a> elements
 sendanalytics('link clicked', {
 documentid: this.props.documentid // specific information to be sent
 });
 }
 };

 render() {
 // ...
 }
}

然而它却存在代码不能复用,组件重构困难等问题

我们可以使用高阶组件来解决这些问题,顾名思义,高阶组件就是一个函数,传给它一个组件,它返回一个新的组件

function withlinkanalytics(mappropstodata, wrappedcomponent) {
 class linkanalyticswrapper extends react.component {
 componentdidmount() {
 reactdom.finddomnode(this).addeventlistener('click', this.onclick);
 }

 componentwillunmount() {
 reactdom.finddomnode(this).removeeventlistener('click', this.onclick);
 }

 onclick = (e) => {
 if (e.target.tagname === 'a') { // naive check for <a> elements
 const data = mappropstodata ? mappropstodata(this.props) : {};
 sendanalytics('link clicked', data);
 }
 };

 render() {
 // simply render the wrappedcomponent with all props
 return <wrappedcomponent {...this.props} />;
 }
 }

 return linkanalyticswrapper;
}

简化代码如下

class document extends react.component {
 render() {
 // ...
 }
}

export default withlinkanalytics((props) => ({
 documentid: props.documentid
}), document);

总结

以上 3 个 react 组件的解耦重构方法都可以直接拿来运用,最开始可能会觉得有点棘手,但是没关系,只要坚持下来,你就会写出更强壮和可复用的代码。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对移动技术网的支持。

原文链接:

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网