热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

简述React中无状态组件和有状态组件的区别

React中的组件主要分为无状态组件和有状态组件两类。1,无状态组件主要用来定义模板,接收来自父组件props传递过来的数据,使用{pro

React中的组件主要分为无状态组件和有状态组件两类。

1,无状态组件主要用来定义模板,接收来自父组件props传递过来的数据,使用{props.xxx}的表达式把props塞到模板里面。无状态组件应该保持模板的纯粹性,以便于组件复用。创建无状态组件如下:

var Header = (props) = (

{props.xxx}

);

2,有状态组件主要用来定义交互逻辑和业务数据(如果用了Redux,可以把业务数据抽离出去统一管理),使用{this.state.xxx}的表达式把业务数据挂载到容器组件的实例上(有状态组件也可以叫做容器组件,无状态组件也可以叫做展示组件),然后传递props到展示组件,展示组件接收到props,把props塞到模板里面。创建有状态组件如下:

class Home extends React.Component {constructor(props) {super(props);};render() {return ( //也可以写成)}
}

这个是官方默认的写法,在构造函数里面默认要传递一个参数进去,并且要调用super()方法,来获取子类的实例。但是比较疑惑的地方是为什么要传递这些参数,传递这些参数有什么用?

因为从render()里面的组件来看,构造函数不传递参数也可以获取到组件实例上的props属性。如下:

class Home extends React.Component {constructor() {super();};render (){return(

);};
};class Header extends React.Component {constructor() {super();};render() {return (
{this.props.name}
//构造函数中并没有传递props属性,这里通过{this.props.name}依然获取到了值);};
};

这个比较好理解,因为render()方法是子组件原型上的方法,获取实例属性的时候要通过this来访问,如果去掉this就获取不到了。

那问题来了,如果我们要在构造函数中访问props改怎么办呢?此时,我们就要在constructor构造函数中传递一个props参数,这样就可以访问到子组件实例上的props属性了。如下:

class Header extends React.Component {constructor(props) {super();this.name = props.name; //获取到子组件实例上的props.name属性,赋值给实例属性name};render() {return (

{this.name}
);};
};

还有一个问题,super(props)方法中为什么也要传递一个props属性呢?看下面的例子:

class Header extends React.Component {constructor(props) {super(props);this.state = {nameOne: props.name,nameTwo: this.props.name //super()方法中传递了props属性,this.props才可以获取到name属性}};render() {return (

{this.state.nameOne}{this.state.nameTwo}
);};
};

其实,props.name和this.props.name的值都是一样的,但是它俩还是有区别的,props.name中这个props就是子组件的属性props,但是this.props.name中的这个props却不是子组件的属性props,虽然值都是一样的,这个props其实在调用super方法的时候被传递到了Component这个父类中去了,所以this.props.name获取到的是Component父类中的props属性。看下React的源码:

图片描述

发现没,子类super方法把props参数传递给了父类Component,Component把props参数挂载到它的实例属性props上了。所以,你只有给super方法中传递props参数,在构造函数里才能用this,props.xxx

如果super方法中不传递props参数,获取this.props.name的值就会报错。获取this.props显示为undifined:如下:

class Header extends React.Component {constructor(props) {super();this.state = {nameOne: this.props.name, nameTwo: this.props };console.log(this.props.name); //报错console.log(this.props); //undifined};render() {return (

{this.state.nameOne}{this.state.nameTwo}
);};
};

这种写法本质是给子组件Header的实例属性state.nameOne和state.nameTwo赋值了一个子组件Header的实例属性props,简单来说,就是Header子组件创建了一个state属性,然后又把自己的props属性赋值给了自己的state属性。
为什么this.props打印出undefined?因为props是调用子组件的时候传入的参数,所以在构造函数内部是访问不到props的,那么对于this.props.name来说,毫无疑问肯定报错。

所以,对与构造函数中的props参数和super中的props参数来说,如果你不在构造函数中用this.props和props,完全可以不用传参。反之就要传参。但是对于this.props和props来说获取到的值都是一样的,所以写哪个都可以。但是官方文档上是两个参数都有写。所以为了严谨,还是都写上吧。

但是,我个人还是喜欢这样的写法。

constructor(props) {super(props);this.state = {name: props.name}
};

不加this的是value,加了this的是key。



推荐阅读
  • 本文将深入探讨如何在不依赖第三方库的情况下,使用 React 处理表单输入和验证。我们将介绍一种高效且灵活的方法,涵盖表单提交、输入验证及错误处理等关键功能。 ... [详细]
  • 本文介绍如何使用 Angular 6 的 HttpClient 模块来获取 HTTP 响应头,包括代码示例和常见问题的解决方案。 ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • 本文详细介绍了 JavaScript 中类 (class) 的基本语法、定义方式、属性保护方法、私有属性的实现以及继承机制。通过具体的代码示例和详细的解释,帮助开发者更好地掌握 JavaScript 类的相关知识。 ... [详细]
  • 本文详细介绍了C++中map容器的多种删除和交换操作,包括clear、erase、swap、extract和merge方法,并提供了完整的代码示例。 ... [详细]
  • 本文介绍了如何使用JavaScript的Fetch API与Express服务器进行交互,涵盖了GET、POST、PUT和DELETE请求的实现,并展示了如何处理JSON响应。 ... [详细]
  • 本文探讨了领域驱动设计(DDD)的核心概念、应用场景及其实现方式,详细介绍了其在企业级软件开发中的优势和挑战。通过对比事务脚本与领域模型,展示了DDD如何提升系统的可维护性和扩展性。 ... [详细]
  • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
  • 探索电路与系统的起源与发展
    本文回顾了电路与系统的发展历程,从电的早期发现到现代电子器件的应用。文章不仅涵盖了基础理论和关键发明,还探讨了这一学科对计算机、人工智能及物联网等领域的深远影响。 ... [详细]
  • Qt QTableView 内嵌控件的实现方法
    本文详细介绍了在 Qt QTableView 中嵌入控件的多种方法,包括使用 QItemDelegate、setIndexWidget 和 setIndexWidget 结合布局管理器。每种方法都有其适用场景和优缺点。 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 微信小程序:授权登录与手机号绑定
    本文详细介绍了微信小程序中用户授权登录及绑定手机号的流程,结合官方指引和实际开发经验,提供了一套完整的实现方案,帮助开发者更好地理解和应用。 ... [详细]
  • 深入解析ESFramework中的AgileTcp组件
    本文详细介绍了ESFramework框架中AgileTcp组件的设计与实现。AgileTcp是ESFramework提供的ITcp接口的高效实现,旨在优化TCP通信的性能和结构清晰度。 ... [详细]
  • SpringMVC RestTemplate的几种请求调用(转)
    SpringMVCRestTemplate的几种请求调用(转),Go语言社区,Golang程序员人脉社 ... [详细]
  • 本文详细介绍如何使用 Python 集成微信支付的三种主要方式:Native 支付、APP 支付和 JSAPI 支付。每种方式适用于不同的应用场景,如 PC 网站、移动端应用和公众号内支付等。 ... [详细]
author-avatar
郭健曲
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有