通过 JavaScript 写页面
在 React 中,页面的编写被融入进 JavaScript 代码。
比如在一个 HTML 网页,写一个如下的简单界面元素(标签):
1 | <h1> |
在 React,会这样写:
1 | let element = React.createElement("h1", null, "没错,这就是一个简单的标签。"); |
而在 HTML 中,要使如上的 h1
标签在网页上展示出来,一般会放到网页结构里:
1 | <html> |
在 React 中,需要使用 ReactDOM.reander()
函数:
1 | let element = React.createElement('h1', null, "没错,这就是一个简单的标签。"); |
而 React 引入的 JSX 其实是对 React.createElement()
的封装,上面的效果如果使用 JSX,代码可能会是这样:
1 | let element = <h1>没错,这就是一个简单的标签。</h1> |
看上面这段代码,我们写 HTML 标签的方式和以往在 HTML 页面中编写是类似的,让人稍微惊讶的是,它 将标签赋值给了一个 JavaScript 变量 。这是 JSX 提供的写法。
回顾一下,按我的简单理解,React 做了一件事 —— 把 HTML 标签的编写融入 JavaScript,为此,提供了 React.createElement()
。
React 提供的 JSX 则对 React.createElement()
又进行封装,使 HTML 元素的编写符合以往的编写方式。(而不是传参这种别扭的方式)当然,JSX 的功能非常强大,条件渲染、列表渲染之类的这里就不细表了。
现在达到的效果便是:通过 JavaScript 写界面,且实际编写方式和以往在 HTML 中操作差别不大。
组件
将页面的编写纳入 JavaScript 后,界面和逻辑便被统一为 JavaScript 代码了。 一个组件往往封装了界面、状态、逻辑,在 Vue 中,一个组件就是一个 .vue
文件,而 在 React 中,一个组件就可以是一个 JavaScript 函数或者一个类 。
React 有两种组件:函数式组件,类组件。
还是拿上面的 HTML 标签举例,把它封装为一个函数式组件,可能是这样:
1 | function Come(props) { |
封装为类组件则像是这样:
1 | class Come extends React.Component { |
值得注意的是,所有的 React 组件都必须是 纯函数。纯函数意味着该函数对于给定的输入,都产生一个相同的输出。简单来说,该函数内部会用到的变量,外部都不能修改。不然即便每次都给一个确定的输入,外部改变了里面会用到的变量,它的输出也会有变化。[1]
这也是 React 强调的「数据的不可变性(immutable)」。
这儿函数内部的变量在 React 被称为 局部状态 。在官方文档 状态(State) 和 生命周期 中,由函数式组件引入到类组件,简单解释说「类定义的组件有一些额外的特性,比如局部状态。」。我觉得它为了入门把这儿简化了,因为函数式组件也可以通过闭包实现自己的局部状态……
可能我理解错了。
函数式组件和类组件从内部来说有什么区别,我也没深了解过。
将组件抽取为类后,组件的扩展就可以使用继承来实现了。 这点是不同于传统 HTML 编写的一个有趣之处。虽然 官方并不建议使用继承来扩展组件。
总结
上面就是我对 React 的初步理解,也是我初次接触 React 感受到的,不同于我之前接触过的界面编写方式(传统界面编写方式、Vue)的地方。
当然,理解可能有误。 保持敬畏,先到这吧。
纯函数是函数式编程中一个核心概念。 ↩︎