90行JS代码构建属于你的React

当我发现 React 所做的一切非常简单,甚至如果我们不是下一家大型初创公司增加筹码,仅需要很少的JS代码就可以构建它 。这也是促使我写这篇文章的动力,希望你读完这篇文章也有相同的感觉 。

作者:刘小夕
来源:Win10系统之家
当我学习 React 的时候,我觉得它所做的一切都是魔术,然后我就开始思考这种魔术究竟是什么 。我感到非常惊讶,当我发现 React 所做的一切非常简单,甚至如果我们不是下一家大型初创公司增加筹码,仅需要很少的JS代码就可以构建它 。这也是促使我写这篇文章的动力,希望你读完这篇文章也有相同的感觉 。
我们将构建什么功能?
  • JSX
  • 函数组件
  • 类组件
  • 生命周期钩子函数
我们不会构建什么?
虚拟DOM
再次为了简单起见,我们不会在本文中实现我们自己的虚拟DOM,我们将使用 snabbdom ,有趣的是,Vue.js 虚拟DOM借鉴了它,你可以在这里读更多关于 snabbdom 的内容:
https://github.com/snabbdom/snabbdom
React Hooks
有些人可能对此感动失望,但是,一口吃不成一个胖子,我们需要一步一步来,因此让我们首先构建基本的东西,然后再在此基础上加以补充 。我计划后续文章中在我们此次构建的内容之上,编写我们自己的 React Hooks 以及虚拟DOM,
可调试性
这是增加任何库或框架的复杂度的关键部分之一,由于我们只是出于娱乐目的而做,因此我们可以放心地忽略 React 提供的可调试性功能,例如 dev tools 和分析器 。
性能和兼容性
我们不会过于关注我们的库的性能,我们只想构建能正常运行的库 。让我们也不要费力地确保它可以在市场上的所有浏览器上使用,只有能够在某些现代浏览器上可以使用,那就已经很好了 。
让我们开始动手
在开始之前,我们需要一个支持ES6,自动热更新的脚手架 。我已经创建了一个非常基础的 webpack 脚手架,你可以进行克隆和设置:
https://github.com/ameerthehacker/webpack-starter-pack
90行JS代码构建属于你的React

文章插图
 
JSX
JSX 是一个开放标准,不仅限于 React,我们可以在没有 React 的情况下使用它,它比你想象得还有容易 。想要了解如何让我们的库支持 JSX ,我们首先需要看看在我们使用 JSX 时背后究竟发生了什么 。
const App = (<div><h1 className="primary">QndReact is Quick and dirty react</h1><p>It is about building your own React in 90 lines of JavsScript</p></div> ); // 上面的 jsx 被转换成下面这样: /*** React.createElement(type, attributes, children)*/ var App = React.createElement("div",null,React.createElement("h1",{className: "primary"},"QndReact is Quick and dirty react"),React.createElement("p",null,"It is about building your own React in 90 lines of JavsScript") ); 正如你看到的,每个 JSX 元素都通过 @
babel/plugin-transform-react-jsx 插件转换为了 React.createElement(...) 函数调用的形式,你可以在这里使用 JSX 进行更多的转换
为了使上述转换运行正常,在编写 JSX 时,你需要引入 React,你就是为什么当你不引入 React 时,编写 JSX 会出现错误的原因 。@
babel/plugin-transform-react-jsx 插件已经添加在了我们的项目依赖中,下面我们先安装一下依赖
npm install 把项目的配置增加到 .babelrc 文件中:
{"plugins": [["@babel/plugin-transform-react-jsx",{"pragma": "QndReact.createElement", // default pragma is React.createElement"throwIfNamespace": false // defaults to true}]] } 此后,只要 Babel 看到 JSX ,它就会调用 QntReact.createElement(...),但是我们还未定义此函数,现在我们将其写到 src/qnd-react.js 中 。
const createElement = (type, props = {}, ...children) => {console.log(type, props, children); }; // 像 React.createElement 一样导出 const QndReact = {createElement }; export default QndReact; 我们在控制台打印出了传递给我们的 type 、 props、 children 。为了测试我们的转换是否正常,我们可以在 src/index.js 中编写一些 JSX。
// QndReact 需要被引入 import QndReact from "./qnd-react"; const App = (<div><h1 className="primary">QndReact is Quick and dirty react</h1><p>It is about building your own React in 90 lines of JavsScript</p></div> ); 启动项目: npm start,在浏览器输入localhost:3000,现在你的控制台看起来应该与下图类似:


推荐阅读