快来跟我一起学 React(Day1)

Posted vv_小虫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快来跟我一起学 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


可以看到,我们成功的将一段 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 


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

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 

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

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 文件看效果:

总结

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

本节课程的完整 Demo 下载

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

欢迎关注我的公众号,每天都有技术文章推送。

以上是关于快来跟我一起学 React(Day1)的主要内容,如果未能解决你的问题,请参考以下文章

快来跟我一起学 React(Day7)

快来跟我一起学 React(Day7)

快来跟我一起学 React(Day6)

快来跟我一起学 React(Day6)

快来跟我一起学 React(Day4)

快来跟我一起学 React(Day4)