快来跟我一起学 React(Day1)

简介

因为目前公司的技术栈都是 Vue,之前有在 React-Native 的项目中接触过 React,但并没有深入的去了解过, 从现在开始,我就把自己当成一个 React 小白了,决定挑战一下自己,从 0 开始入手 React,中间会不断的跟 Vue 进行对比,跟紧节奏,我们一起出发吧。

知识点

  • React 简介
  • JSX 简介
  • Babel 语法转换
  • @babel/preset-react
  • @vue/babel-preset-jsx
  • Hello React

React 是什么?

我就不解释什么是 React 了,相信网上随便一搜都是一大堆,截止目前为止 github 上的 star 人数已经 165k 了。

因为在 React 项目中,大部分使用的都是 JSX 语法,所以在正式学习 React之前,我们先来了解 JSX 语法。

JSX 简介

它被称为 JSX,是一个 JavaScript 的语法扩展。建议在 React 中配合使用 JSX,JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模板语言,但它具有 JavaScript 的全部功能。

比如:

const element = <h1>Hello, world!</h1>;

最后经过工具转换成 React 节点实例会变成这样:

var a = /*#__PURE__*/React.createElement("div", null, "123123");

其实就是以上结果的一个简写,最初也就是 React 开发人员为了写代码方便定义的一种规范,大家用着用着觉得蛮不错的,所以逐渐成为了一种规范了。

同样是上面的代码,经过工具转换成 Vue 节点实例会变成这样:

const element = h("h1", ["Hello, world!"]);

下面我们利用 Babel 分析一下 ReactVue 转换 JSX 语法的过程。

Babel 对 JSX 转换

Babel 是啥我就不解释了,可以看一下官网的简介,或者感兴趣的小伙伴可以看一下我之前些的一些文章:

我们直接上代码测试一下。

首先我们创建一个 babel-jsx 目录:

mkdir babel-jsx

然后在 babel-jsx 目录执行以下命令初始化 npm:

npm init -y

接着安装 @babel/cli@babel/core

npm install -D @babel/cli @babel/core

然后创建一个 src 目录,并在 src 目录中创建一个 test1.js 文件:

mkdir src && touch ./src/test1.js

然后将以下代码写入到 src/test1.js 文件:

// 需要转换的代码
const code = `
    const element = <h1>Hello, world!</h1>;
`;
const {parse} = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const t = require("@babel/types");
const generator = require("@babel/generator").default;

// 获取语法 ast 语法树
const ats = parse(code, {
    sourceType: "module",
    plugins: [
        "jsx"
    ]
});
// 开始遍历 ast 语法树
traverse(ats, {
    exit(path) {
        // 当判断是 JSX 节点的时候
        if (t.isJSXElement(path.node)) {
            // 替换当前的 JSX 节点
            path.replaceWith(
                t.callExpression(
                    t.identifier('h'),
                    [
                        t.stringLiteral(path.node.openingElement.name.name),
                        t.arrayExpression([t.stringLiteral(path.node.children[0].value)])
                    ])
            );
        }
    }
});
// 输出转换过后的 ast 语法树
console.log(generator(ats));

这就是 babel 进行转换的过程了,(不懂的童鞋强烈推荐去看一下我之前的文章 babe从入门到精通:https://vvbug.blog.csdn.net/article/details/107092536)有这么几个过程:

  1. 准备需要转换的代码

     const element = <h1>Hello, world!</h1>;
    
  2. 利用 @babel/parser 将代码转换成 AST 语法树

    // 获取语法 ast 语法树
    const ats = parse(code, {
        sourceType: "module",
        plugins: [
            "jsx"
        ]
    });
    
  3. 利用 @babel/traverse 遍历 AST 语法树

    // 开始遍历 ast 语法树
    traverse(ats, {
        exit(path) {
          ....
        }
    
  4. 利用 @babel/generatorAST 语法树转换成代码

    // 输出转换过后的 ast 语法树
    console.log(generator(ats));
    

我们可以测试一下。

babel-jsx 目录下执行以下命令运行 src/test1.js 文件:

 node ./src/test1.js
1-1.png

可以看到,我们成功的将一段 JSX 语法代码转换成了 Vue 中的一个节点实例了。

@babel/preset-react

@babel/preset-reactBabel 官方提供的一个用来转换 JSX 语法为 React 节点的 Babel 插件集合。

@babel/preset-react 官网地址:https://babeljs.io/docs/en/babel-preset-react

我们来试用一下。

首先安装 @babel/preset-react

npm install -D @babel/preset-react

接着我们在 src 目录下创建一个 test2.jsx 文件进行测试,src/test2.jsx 文件内容:

const element = <h1>Hello, world!</h1>;

最后我们在babel-jsx 目录下执行以下命令完成 babel 编译:

npx babel ./src/test2.jsx --presets @babel/preset-react 
1-2.png

可以看到,直接将我们的源代码:

const element = <h1>Hello, world!</h1>;

转换成了:

const element = /*#__PURE__*/React.createElement("h1", null, "Hello, world!");

其实经过上面 babel 例子分析我们知道,@babel/preset-react 做的事情无非就是 babeltraverse 过程中的一些节点的处理。

@vue/babel-preset-jsx

@vue/babel-preset-jsxVue 官方提供的一个用来转换 JSX 语法为 Vue 节点的 Babel 插件集合。

@vue/babel-preset-jsx 官网地址:https://github.com/vuejs/babel-plugin-transform-vue-jsx

同样,我们也来试用一下。

首先安装 @vue/babel-preset-jsx

npm install -D @vue/babel-preset-jsx

然后我们在babel-jsx 目录下执行以下命令完成 babelsrc/test2.jsx 文件的编译:

npx babel ./src/test2.jsx --presets @vue/babel-preset-jsx 
1-3.png

可以看到,直接将我们的源代码:

const element = <h1>Hello, world!</h1>;

转换成了:

const element = h("h1", ["Hello, world!"]);

原理跟 @babel/preset-react 一样。

Hello React

哈哈,学习 React 第一天怎么能少了 "Hello React" 呢?我们总得先体验一下吧。

ok,我们首先在 babel-jsx 目录下创建一个 test.html 文件用来测试:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 导入 React 接口库 -->   
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <!-- 导入 React-Dom 接口库 -->   
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
</head>
<body>
    <!-- 根节点,用来挂载 React 根节点 --> 
    <div id="root"></div>
    <!-- 引入 babel 编译过后的入口文件 --> 
    <script src="./dist/test3.js"></script>
</body>
</html>

然后我们在 src 目录下创建一个 test3.jsx 文件:

ReactDOM.render(
    <h1>Hello React!</h1>,
    document.getElementById('root')
);

很简单,我们用 JSX 语法创建了一个 "h1" 节点,然后把这个节点当成 React 的根节点挂载到了 root 节点上。

接下来我们执行 babel 编译命令:

npx babel ./src/test3.jsx -o ./dist/test3.js --presets @babel/react

编译成功后,我们点开 dist/test3.js 文件:

ReactDOM.render( /*#__PURE__*/React.createElement("h1", null, "Hello React!"), document.getElementById('root'));

可以看到,babel 将我们的 JSX 语法内容转换成了 js 语法内容。

最后我们在浏览器打开 test.html 文件看效果:

1-4.png

总结

我们认识了什么是 JSX ,并且用 babel 分析了 JSX 语法的编译过程,最后利用 CDN + Babel 完成了 "Hello React" 的输出,这一节还是比较轻松的,后面马上我们就会进入到 Reactapi 的分析,我们将结合 Demo 深入到 React 的源码,一起加油吧!

本节课程的完整 Demo 下载

https://gitee.com/vv_bug/react-day1-1/tree/develop/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容