从原生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 相关文章推荐
Add a Picture to a Microsoft Word Document
Jun 15 Javascript
jQuery EasyUI 中文API Button使用实例
Apr 14 Javascript
jQuery find和children方法使用
Jan 31 Javascript
jquery实现的让超出显示范围外的导航自动固定屏幕最顶上
Sep 22 Javascript
js+JQuery返回顶部功能如何实现
Dec 03 Javascript
详解Bootstrap的aria-label和aria-labelledby应用
Jan 04 Javascript
Node.js中路径处理模块path详解
Nov 14 Javascript
JavaScript 计算笛卡尔积实例详解
Dec 02 Javascript
ionic2打包android时gradle无法下载的解决方法
Apr 05 Javascript
Vue 全局loading组件实例详解
May 29 Javascript
Vue 列表上下过渡效果的实例代码
Jun 25 Javascript
javascript中call,apply,bind的区别详解
Dec 11 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
杏林同学录(一)
2006/10/09 PHP
PHP 函数语法介绍一
2009/06/14 PHP
php下mysql数据库操作类(改自discuz)
2010/07/03 PHP
php警告Creating default object from empty value 问题的解决方法
2014/04/02 PHP
关于COOKIE个数与大小的问题
2011/01/17 Javascript
终于解决了IE8不支持数组的indexOf方法
2013/04/03 Javascript
在JavaScript并非所有的一切都是对象
2013/04/11 Javascript
JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
2013/12/31 Javascript
html的DOM中document对象images集合用法实例
2015/01/21 Javascript
Nodejs关于gzip/deflate压缩详解
2015/03/04 NodeJs
JavaScript 计算笛卡尔积实例详解
2016/12/02 Javascript
简单实现bootstrap选项卡效果
2017/02/08 Javascript
js判断用户是输入的地址请求的路径(实例讲解)
2017/07/18 Javascript
简单明了区分escape、encodeURI和encodeURIComponent
2018/05/26 Javascript
NodeJS模块与ES6模块系统语法及注意点详解
2019/01/04 NodeJs
JavaScript常用工具函数库汇总
2020/09/17 Javascript
vue-resource 拦截器interceptors使用详解
2021/01/18 Vue.js
[01:08]2014DOTA2展望TI 剑指西雅图LGD战队专访
2014/06/30 DOTA
Python 详解基本语法_函数_返回值
2017/01/22 Python
基于Pandas读取csv文件Error的总结
2018/06/15 Python
Python中collections模块的基本使用教程
2018/12/07 Python
Python 过滤错误log并导出的实例
2019/12/26 Python
学生如何注册Pycharm专业版以及pycharm的安装
2020/09/24 Python
calendar在python3时间中常用函数举例详解
2020/11/18 Python
HTML5页面中尝试调起APP功能
2017/09/12 HTML / CSS
size?荷兰官方网站:英国高级运动鞋精品店
2020/07/24 全球购物
应用数学自荐书范文
2013/11/24 职场文书
日语求职信范文
2013/12/17 职场文书
办理暂住证介绍信
2014/01/11 职场文书
入党积极分子介绍信
2014/01/17 职场文书
回门宴父母答谢词
2014/01/26 职场文书
承诺书格式
2014/06/03 职场文书
捐书活动倡议书
2015/04/27 职场文书
个人工作总结(管理人员)范文
2019/08/13 职场文书
python3读取文件指定行的三种方法
2021/05/24 Python
pandas时间序列之pd.to_datetime()的实现
2022/06/16 Python