每天一点面试题(16)--------虚拟DOM

JSX的背后

这个过程一般在前端会称为“转译”,但其实“汇编”将是一个更精确的术语。

React开发人员敦促你在编写组件时使用一种称为JSX的语法,混合了HTML和JavaScript。但浏览器对JSX及其语法毫无头绪,浏览器只能理解纯碎的JavaScript,所以JSX必须转换成JavaScript。这里是一个div的JSX代码,它有一个class name和一些内容:

<div className='cn'>
  Content!
</div>

以上的代码,被转换成“正经”的JavaScript代码,其实是一个带有一些参数的函数调用:

React.createElement(
  'div',
  {
    className: 'cn' },
  'Content!'
);

让我们仔细看看这些参数。

  1. 第一个是元素的type。对于HTML标签,它将是一个带有标签名称的字符串。
  2. 第二个参数是一个包含所有元素属性(attributes)的对象。如果没有,它也可以是空的对象。
  3. 剩下的参数都可以认为是元素的子元素(children)。元素中的文本也算作一个child,是个字符串’Content!’ 作为函数调用的第三个参数放置。

你应该可以想象,当我们有更多的children时会发生什么:

<div className='cn'>
  Content 1!
  <br />
  Content 2!
</div>
React.createElement(
  'div',
  {
    className: 'cn' },
  'Content 1!',              // 1st child
  React.createElement('br'), // 2nd child
  'Content 2!'               // 3rd child
)

我们的函数现在有五个参数:

一个元素的类型
一个属性对象
三个子元素。

因为其中一个child是一个React已知的HTML标签(
),所以它也会被描述为一个函数调用(React.createElement(‘br’))。

到目前为止,我们已经涵盖了两种类型的children:

简单的String
另一种会调用React.createElement。

然而,还有其他值可以作为参数:

基本类型 false, null, undefined, true
数组
React Components

可以使用数组是因为可以将children分组并作为一个参数传递:

React.createElement(
  'div',
  {
    className: 'cn' },
  ['Content 1!', React.createElement('br'), 'Content 2!']
)

当然了,React的厉害之处,不仅仅因为我们可以把HTML标签直接放在JSX中使用,而是我们可以自定义自己的组件,例如:

function Table({
    rows }) {
   
  return (
    <table>
      {
   rows.map(row => (
        <tr key={
   row.id}>
          <td>{
   row.title}</td>
        </tr>
      ))}
    </table>
  );
}

组件可以让我们把模板分解为多个可重用的块。在上面的“函数式”(functional)组件的例子里,我们接收一个包含表格行数据的对象数组,最后返回一个调用React.createElement方法的

元素,rows则作为children传进table。

无论什么时候,我们这样去声明一个组件时:

<Table rows={
   rows} />

从浏览器的角度来看,我们是这么写的:

React.createElement(Table, {
    rows: rows });

注意,这次我们的第一个参数不是String描述的HTML标签,而是一个引用,指向我们编写组件时编写的函数。组件的attributes现在是接收的props参数了。

把组件(components)组合成页面(a page)

所以,我们已经将所有JSX组件转换为纯JavaScript,现在我们有一大堆函数调用,它的参数会被其他函数调用的,或者还有更多的其他函数调用这些参数…这些带参数的函数调用,是怎么转化成组成这个页面的实体DOM的呢?

为此,我们有一个ReactDOM库及其它的render方法:

function Table({
    rows }) {
    /* ... */ } // defining a component

// rendering a component
ReactDOM.render(
  React.createElement(Table, {
    rows: rows }), // "creating" a component
  document.getElementById('#root') 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值