实现 Toy-React , 实现 JSX 渲染(上)

简介: 实现 Toy-React , 实现 JSX 渲染

image.png

一、简介

JSX 是属于 React 中的一大特性,因此,本文将实现自定义 JSX 渲染功能,同时也会实现部分 React 中拥有的功能,以便加深理解.

二、准备工作

目录结构

目录结构比较简单,就不详细说明了

image.png

webpack 配置

  • 由于我们需要在 .js 或者 .jsx 文件中编写 jsx 语法,同时,也为了我们可以使用一些 js 新特性,因此需要通过 webpack 中的 loader 配置进行编译.
  • 这里我们需要用到的 loader 如下:
  • babel-loader
  • @babel/core
  • @babel/preset-env:js 转换为运行环境能识别的语法
  • @babel/plugin-transform-react-jsx:JSX 语法转换为对应内容的输出结果
  • 为了避免多次手动执行 webpack 编译命令,这里是使用了 webpack-dev-server 来监听文件变化,自动执行编译命令

image.png

  • 配置文件内容如下
const path =  require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  mode: "development",
  entry: {
    main: "./main.jsx",
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
            plugins: [
              [
                "@babel/plugin-transform-react-jsx",
                { pragma: "createElement" },
              ],
            ],
          },
        },
        exclude: /node_modules/,
      },
    ],
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "My App",
      template: "public/index.html",
    }),
  ],
  optimization: {
    minimize: false,
  },
};
复制代码

三、编写 JSX

1. 首先在 main.jsx 中编写一段简单的 JSX 内容

image.png

2. 观察被编译的结果

image.png

  • 从以上结果可以看到,最终 JSX 语法被 @babel/plugin-transform-react-jsx 被编译成了 React.createElement 方法,由此可见,要实现 JSX 渲染的关键就是要实现 createElement
  • 这里我们要调整一下编译后的结果,我们需要 jsx 被编译为我们自定义的 createElement 方法,而不是 React.createElement,因此我们修改 webpack 配置文件中与 "@babel/plugin-transform-react-jsx" 相关的配置为
module: {
    rules: [
      {
        test: /\.jsx$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
            plugins: [
              [
                "@babel/plugin-transform-react-jsx",
                { pragma: "createElement" }, // 这里就是控制 jsx 语法被编译后要调用的方法名
              ],
            ],
          },
        },
        exclude: /node_modules/,
      },
    ],
复制代码

3. 自定义实现 createElement 方法

从编译后的结果来看 createElement 方法具有三个参数:

  • type —— 当前元素的类型:HTML标签名、Class 组件、Function 组件
  • attributes —— 当前元素上的拥有的属性:{ } || null
  • children —— 除了前两个参数,默认后面的参数全部为当前元素的子节点:[ ]
function createElement(type, attributes,...children){
  // 创建 dom 实例
  const currentElement = document.createElement(type);
  // 处理属性
  if(attributes){
    for (const name in attributes) {
      currentElement.setAttribute(name, attributes[name]);
    }
  }
  // 处理子节点
  if(children.length){
    for (let child of children) {
      // 处理文本节点
      if(typeof child === "string"){
        child = document.createTextNode(child);
      }
      currentElement.appendChild(child);
    }
  }
  return currentElement;
}
const JSX = (<div class="jsx">
  <h1>i am Jsx</h1>
</div>);
document.body.appendChild(JSX);
复制代码

到这里,现在已经可以将简单的 JSX 渲染成了视图

image.png

四、升级改造 createElement

1. 虽然现在我们已经可以渲染简单的 JSX 内容了,但是如果要渲染 Class 组件或者 Function 组件的话,createElement 方法明显还无法做到,于是我们需要对其进行升级改造.

2. 同样,我们先观察如果使用 Class 组件,那么最终会被编译为什么呢?

class MyComponent {
  render() {
    return (<div>
      <h1>i am MyComponent</h1>
      </div>);
  }
}
const JSX = (
  <div id="jsx">
    <h1>i am Jsx</h1>
    <MyComponent id="MyComponent">
      <h1>i am MyComponent child</h1>
    </MyComponent>
  </div>
);
复制代码


image.png

目录
相关文章
|
1月前
|
前端开发 JavaScript
React如何进行条件渲染
React如何进行条件渲染
17 0
|
1月前
|
前端开发 JavaScript 开发者
React:JSX语法入门
React:JSX语法入门
40 0
|
1月前
|
前端开发 JavaScript 算法
React渲染流程
应用的性能和灵活性,以后可以具体看一 Fiber 的工作原理。
22 3
|
23天前
|
前端开发 JavaScript
REACT 条件渲染
REACT 条件渲染
|
1月前
|
存储 前端开发 JavaScript
在回调函数中重新渲染React组件
在React中,重新渲染组件可通过`forceUpdate()`或`ReactDOM.render()`实现。方法一是使用`forceUpdate`强制无状态组件更新;方法二是通过重新创建根组件实例适用于有状态组件。这些示例基于Webpack和Babel的模块热替换配置。根据项目需求和React版本,还可以结合React-Router或Redux等库选择合适的方法。
|
1月前
|
XML 前端开发 JavaScript
react中JSX的详解
react中JSX的详解
24 2
|
1月前
|
存储 JSON 资源调度
next.js博客搭建_react-markdown渲染内容(第三步)
next.js博客搭建_react-markdown渲染内容(第三步)
16 1
|
1月前
|
数据采集 资源调度 前端开发
React的服务器端渲染:使用ReactDOMServer进行高效页面预渲染
【4月更文挑战第25天】使用ReactDOMServer,React支持服务器端渲染以实现高效预渲染。通过在Node.js环境中将React组件转化为HTML字符串,减少客户端JavaScript负载和渲染时间。优点包括更快首屏加载、改善SEO和兼容无JavaScript环境,但也会增加服务器负载、复杂性和状态管理挑战。开发者需根据项目需求平衡SSR和CSR。
|
1月前
|
前端开发 JavaScript 安全
React中的JSX:语法与原理深入解析
【4月更文挑战第25天】本文深入解析React中的JSX,一种JavaScript语法扩展,使代码更直观。JSX让开发者以HTML样式描述组件UI,但最终编译成JavaScript。通过Babel转换,JSX标签转为React.createElement()调用,创建虚拟DOM。JSX的优势在于直观性、类型安全、代码复用和工具支持,助力高效开发React组件,适应不断发展的Web应用需求。
|
1月前
|
前端开发 JavaScript
React中渲染html结构---dangerouslySetInnerHTML
React中渲染html结构---dangerouslySetInnerHTML
30 0