从原生JavaScript到React深入理解


Posted in Javascript onJuly 23, 2022

从头开始理解 React

作者:Stéphane Bégaudeau

翻译原文 https://www.sbegaudeau.com/2018/10/01/from-vanilla-javascript-to-react.html

React 是一个用于构建用户界面的 JavaScript 框架。它可用于通过动态操作页面内容来创建 JavaScript 应用程序。浏览器已经提供了在页面中创建元素的 API,即 DOM,所以新手可能想知道 React 带来了什么以及它与 DOM 的关系。

原生 JavaScript 和 DOM

在 JavaScript 中,就像在大多数编程语言中一样,您将可以访问具有各种对象和函数的全局范围,您可以操纵这些对象和函数来构建您的应用程序。在 Web 环境中运行的 JavaScript 应用程序中,您将有权访问文档对象模型 (DOM) API。如果您在基于节点的应用程序中使用 JavaScript,您将无法访问 DOM,但您可以导入替代实现,例如JSDOM。

DOM 是一个简单的 API,可让您以几乎任何您想要的方式操作页面的 HTML 文档。由于全局document 对象,您可以开始使用它。

从 document 这里开始,您可以轻松地创建新元素、修改它们的属性,甚至将它们添加为其他元素的子元素。多亏了 DOM,您可以通过编程方式创建任何 HTML 文档,即使这样做会非常冗长。

在下面的示例中,我们将以编程方式在 HTML 文档中创建一个简单的标题。

<!DOCTYPE html>
<html>
  <head>
    <script src="app.js"></script>
  </head>
  <body>
    <div id="app" />
  </body>
</html>

为此,我们将创建一个h1元素,该元素将插入到 HTML 页面的正文中。

// The document object is accessible since it is in the global scope
const h1Element = document.createElement('h1');
h1Element.setAttribute('class', 'title');
const textElement = document.createTextNode('I am Groot');
h1Element.appendChild(textElement);
// document.getElementById('app') will retrieve the div with the identifier app
document.getElementById('app').appendChild(element);

上面的代码首先创建一个新属性,然后向该元素h1添加一个class带有值为title的新属性。 它还创建一个简单的文本节点并将文本 'I am Groot' 添加为元素h1的子元素。最后,它使用 HTML 文档将 h1 的标签添加到 div 中。app 执行此代码后,生成的 HTML 文档将如下所示:

<!DOCTYPE html>
<html>
  <head>
    <script src="app.js"></script>
  </head>
  <body>
    <div id="app">
      <h1 class="title">I am Groot</h1>
    </div>
  </body>
</html>

借助 DOM,我们还可以通过 className 属性直接操作元素的类属性(因为名称 class 是 JavaScript 中的保留关键字)。因此,以下代码将产生完全相同的结果。

const h1Element = document.createElement('h1');
// h1Element.setAttribute('class', 'title');
h1Element.className = 'title';
const textElement = document.createTextNode('I am Groot');
h1Element.appendChild(textElement);
document.getElementById('app').appendChild(element);

React 的基础

大多数 React 教程会让你从直接使用 React 的所有奇迹开始。我们将采用另一种方法,因为我们将从编写一些你可能永远不会再编写的 React 代码开始,以便更好地理解 React 的工作方式。

React 的创建考虑了 Web 应用场景,因此,在其核心,它的一些 API 感觉就像 DOM。为了说明这一点,我们将看一下最重要的 React API 之一,React.createElement.

要使用 React 操作 DOM,您将需要两个依赖项 React 和 ReactDOM. React.createElement将让您创建一个廉价且快速的数据结构,称为虚拟 DOM,代表您的用户界面的结构。ReactDOM将在您的 Web 应用程序的真实 DOM 中呈现这个虚拟 DOM。

React.createElement将需要三个参数来创建虚拟 DOM 的元素:

  • 要创建的元素的名称
  • 它的属性
  • 它的孩子
import React from 'react';
const name = 'h1';
const props = { className: 'title' };
const children = 'I am Groot';
const element = React.createElement(name, props, children);

React.createElement 也可以接受包含要创建的元素的所有子元素的数组。

import React from 'react';
const name = 'h1';
const props = { className: 'title' };
const children = ['I am Groot'];
const element = React.createElement(name, props, children);

参数 children 也是元素的常规属性,因此它可以是 props 对象的一部分。

import React from 'react';
const props = {
  className: 'title',
  children: ['I am Groot']
};
const element = React.createElement('h1', props);

为了在 DOM 中渲染这个元素,我们需要选择它在 DOM 中的渲染位置,在我们的例子中是div带有标识符app并告诉 ReactDOM 渲染它。

import React from 'react';
import ReactDOM from 'react-dom';
const props = {
  className: 'title',
  children: ['I am Groot']
};
const element = React.createElement('h1', ...props);
ReactDOM.render(element, document.getElementById('app'));

此处显示的所有代码示例都可以通过将它们与未打包版本的 React 和 Babel 一起使用来进行测试。这样的配置应该只用于简单的测试,因为它们没有像生产构建那样优化。在这种特定情况下,应删除 和 的导入(此处均作为全局变量公开react)。react-dom

<!DOCTYPE html>
<html>
  <head>
    <title>React</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script type="text/babel">
    const props = {
      className: 'title',
      children: ['I am Groot']
    };
    const element = React.createElement('h1', props);
    ReactDOM.render(element, document.getElementById('app'));
    </script>
  </head>
  <body>
    <div id="app" />
  </body>
</html>

咱老百姓也能学会的 JSX

虽然我们可以使用这种方法创建 Web 应用程序的所有页面,但它仍然非常冗长。为了使操作 DOM 变得容易,React 提供了一种名为JSX的简单而强大的语言。

预处理器使用 JSX 在构建期间将其转换为常规 JavaScript。一个常规的 React 项目使用预处理器来将 JSX 代码转换为对 React.createElement. 因此,JSX 永远不会被 React 直接解释,你可以在没有一行 JSX 的情况下使用 React。因此,下面的两段代码完全相同。首先,以编程方式使用 React:

import React from 'react';
const props = { className: 'title' };
const children = ['I am Groot'];
const element = React.createElement('h1', props, children);

或使用 JSX 声明:

import React from 'react';
const element = &lt;h1 className="title"&gt;I am Groot&lt;/h1&gt;;

由于 JSX 代码将使用 转换为调用 React.createElement,因此您需要导入 React,即使它似乎没有被使用。

使用 JSX,您可以非常快速地以声明方式创建大部分 DOM,而 React 只会看到对React.createElement. 由于 JSX 元素只是对 的调用 React.createElement,因此 children 仍然是常规属性。因此,您也可以像这样编写前面的示例:

import React from 'react';
const element = &lt;h1 className="title" children="I am Groot"/&gt;;

借助 JSX,您可以通过花括号访问变量:

import React from 'react';
const title = 'title';
const text = 'I am Groot';
const element = &lt;h1 className={title} children={text}/&gt;;

当然,我们也可以将变量命名为我们想要操作的属性

import React from 'react';
const className = 'title';
const children = 'I am Groot';
const element = &lt;h1 className={className} children={children}/&gt;;

这将允许我们使用扩展语法来获得更简洁的代码

import React from 'react';
const props = {
  className: 'title',
  children: ['I am Groot']
};
const element = &lt;h1 {...props}/&gt;;

最后,我们可以像以前一样在 DOM 中渲染这个元素 React.createElement。

import React from 'react';
import ReactDOM from 'react-dom';
const props = {
  className: 'title',
  children: ['I am Groot']
};
ReactDOM.render(&lt;h1 {...props}/&gt;, document.getElementById('app'));

现在我们已经使用 JSX 通过 React 渲染了我们的第一块虚拟 DOM,我们准备好看看如何使用 React 构建一个基本的应用程序。

奔跑吧,去用 React 组件开发更多动态代码。

以上就是从原生JavaScript到React深入理解的详细内容,更多关于原生JavaScript到React的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
深入理解JavaScript定时机制
Oct 29 Javascript
js确认删除对话框效果的示例代码
Feb 20 Javascript
完美兼容各大浏览器获取HTTP_REFERER方法总结
Jun 24 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
Apr 12 Javascript
js a标签点击事件
Mar 30 Javascript
DVA框架统一处理所有页面的loading状态
Aug 25 Javascript
浅析为什么a=&quot;abc&quot; 不等于 a=new String(&quot;abc&quot;)
Oct 25 Javascript
vue实现微信分享朋友圈,发送朋友的示例讲解
Feb 10 Javascript
Vue.directive使用注意(小结)
Aug 31 Javascript
微信运维交互机器人的示例代码
Nov 12 Javascript
Vue.js 中 axios 跨域访问错误问题及解决方法
Nov 21 Javascript
如何利用js在两个html窗口间通信
Apr 27 Javascript
JS前端监控采集用户行为的N种姿势
Jul 23 #Javascript
JS前端可扩展的低代码UI框架Sunmao使用详解
Jul 23 #Javascript
uniapp引入支付宝原生扫码插件步骤详解
Jul 23 #Javascript
JS前端宏任务微任务及Event Loop使用详解
Jul 23 #Javascript
关于对TypeScript泛型参数的默认值理解
Jul 15 #Javascript
vue递归实现树形组件
Jul 15 #Vue.js
VUE递归树形实现多级列表
Jul 15 #Vue.js
You might like
PHP学习资料汇总与网址
2007/03/16 PHP
smarty模板判断数组为空的方法
2015/06/10 PHP
PHP编程计算文件或数组中单词出现频率的方法
2017/05/22 PHP
PHP使用Nginx实现反向代理
2017/09/20 PHP
PHP设计模式之注册树模式分析
2018/01/26 PHP
php empty 函数判断结果为空但实际值却为非空的原因解析
2018/05/28 PHP
jQuery实现页面滚动时层智能浮动定位实例探讨
2013/03/29 Javascript
JS继承--原型链继承和类式继承
2013/04/08 Javascript
jquery操作select大全
2014/04/25 Javascript
使用GruntJS构建Web程序之Tasks(任务)篇
2014/06/06 Javascript
ext中store.load跟store.reload的区别示例介绍
2014/06/17 Javascript
简单总结JavaScript中的String字符串类型
2016/05/26 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(一)之数据支持json字符串、list集合
2016/08/11 Javascript
Javascript继承机制详解
2017/05/30 Javascript
Vue+SpringBoot开发V部落博客管理平台
2017/12/27 Javascript
安装vue-cli的简易过程
2018/05/22 Javascript
vue中v-text / v-html使用实例代码详解
2019/04/02 Javascript
微信网页登录逻辑与实现方法
2019/04/29 Javascript
vuex 实现getter值赋值给vue组件里的data示例
2019/11/05 Javascript
详解JavaScript中的数据类型,以及检测数据类型的方法
2020/09/17 Javascript
Python中函数的用法实例教程
2014/09/08 Python
零基础写python爬虫之抓取糗事百科代码分享
2014/11/06 Python
整理Python 常用string函数(收藏)
2016/05/30 Python
python简单读取大文件的方法
2016/07/01 Python
Python随机生成手机号、数字的方法详解
2017/07/21 Python
python中logging模块的一些简单用法的使用
2019/02/22 Python
pandas 数据结构之Series的使用方法
2019/06/21 Python
Python列表与元组的异同详解
2019/07/02 Python
canvas离屏技术与放大镜实现代码示例
2018/08/31 HTML / CSS
PHP面试题大全
2015/10/16 面试题
是否有自动比较结构的方法
2015/06/03 面试题
在weblogic中发布ejb需涉及到哪些配置文件
2012/01/17 面试题
Python中如何定义一个函数
2016/09/06 面试题
优秀教师先进个人事迹材料
2014/08/31 职场文书
导游词之台湾安平古堡
2019/12/25 职场文书
教你在 Java 中实现 Dijkstra 最短路算法的方法
2022/04/08 Java/Android