javascript - react 组件两种声明方式疑问
高洛峰
高洛峰 2017-04-11 13:32:16
[JavaScript讨论组]

方式一:

import React from 'react';

class GameView extends  React.Component{
}

export default GameView;

方式二:

import React from 'react';

const GameView = ({}) => {
}

export default GameView;

第一种方式是es6的,我经常见,但是最近看别人代码,发现了第二种定义方式。
第二种导入了React库,却没使用,也定义成功了,怎么实现的?

非常感谢 @cheoyx @eyesofkids 详细解答,我突然发现,我基本没有看过React的文档,我来公司之后,学习React都是参考的公司前辈,大神们的源码。看源码确实学习的非常快,但是基础的东西却不清楚。之后,我会认真的看一下官方文档的。谢谢大家。

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(2)
阿神

在React v15中,我们共有三种方式可以定义一个组件。大概是React的设计者们认为,多几种方式可以让不同需求的开发者增加来使用React的诱因,菜色不同但都可以吃好吃饱。另一方面也可以在不同情况下使用不同定义方式,各有一些好处,简单的效率好,复杂的弹性多。

第一种是你说的ES6方式,因为它里面有超出ES6标准的语法,通常称为ES6+的类定义方式,是使用继承自React.Component类别的语法,这样式又可以称为建构式样式(constructor pattern)。因为现在可以直接执行ES6+相关语法与API的浏览器,通常会需要要新版本的浏览器,而且还不见得会100%相容。所以我们一般都会先经由babel工具帮忙先转成ES5语法再执行,这样在浏览器各种不同版本与品牌中,可以得到最大的相容程度。不过ES6+是一种未来将会普及的语法,也是时间早晚的问题而已。现在官方已经都换这种方式来写文件或教程了。

第二种是ES5的语法,这是为了要能相容于只支援ES5的浏览器,所使用的一种方式。最早React的版本中只有这种方式,所以网上的范例有很多都是用这种语法,如果你连JSX语法也不使用的话,那么是完全可以不需要babel工具,就可以在各种支援ES5标准的浏览器中执行。这种样式又可以称之为工厂样式(factory pattern)。下面是例子代码:

var HelloWorld = React.createClass({
  render: function() {
    return <h1>{this.props.text}</h1>
  }
});

第三种是是函数(函式)定义样式,这只能在无状态的功能性元件(Stateless functional components)上使用,像我们上面的HelloWorld组件就是无状态的(stateless),里面没有定义state值与相关生命周期的方法。纯粹是个显示用的简单元件,所以可以用这个语法。这个语法是在React 0.14版本才加入的,也是前不久的事情而已(2015.10)。通常这个样式还会使用ES6中的箭头函式语法,让程式码更简洁,不过它看起来不太像是个很厉害的组件,纯粹是个函数(式)而已:

 const HelloWorld = (props) => (
   <h1>{props.text}</h1>
 )

注: React的最近版本是从0.14直接大跳板号到15.0的。

注: 箭头函式的后面使用括号(())是只有单个语句时使用的,会自动加上return在语句前。如果是多行语句要用花括号({}),而且要加上return的语句。

函数(函式)定义方式有一些限制与规则,大致如下,太细可能要查文档:

  • 里面不能有state(状态)。

  • 里面不能用生命周期的方法,例如componentDidMount全部不行。

  • propTypes屬性可以用,但要写在寫在函式區塊的"外面"

  • 有用到JSX语句还是要import(引入)React函式库,JSX语法相当于要调用React.createElement方法,所以需要。

这个函式定义方式现在在redux中有变化应用方式出现,就是拿来再区分为容器组件(Container Components)与呈现组件(Presentational Components),即是以函数型的组件解决方式,完全舍弃类(建构式样式)或工厂样式,是一种更简洁的体现。

天蓬老师

看文档,react开发最基本的要求就是看完docs页面左边quick start,advanced guides和部分reference的内容,

你说的这种叫做stateless component或者functional component,原文说的很清楚,这就是一个javascript 函数,(We call such components "functional" because they are literally JavaScript functions.)https://facebook.github.io/re...
只不过用jsx语言写而已,就和typescript写一个js函数和你正常写的看起来也不太一样,但其实最终是一个东西,比如你可以写一个这个组件通过babel编译之后在浏览器里看一下他的样子

再多说一点,关于你第二种组件引入react库却没有明确的调用(类似extends React.Component这样)为什么可以工作的问题

可以看出你对于面向对象中继承的概念不够明确,面向对象中通过继承使新的class获得一些初始就有的方法,属性,第一种组件就通过继承React.Component获得了render的方法,还有生命循环方法等,他会在合适的时候执行合适的方法。

第二种组件,他所做的就是计算需要的数据,然后生成一个react能处理的组件结构,就是一个纯函数,所以不需要继承

之所以需要import React,是为了在这个文件的scope内有react以供调用(没看过源码,但应该是这样)

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号