目录
1.React框架的介绍
React、Angular、Vue.js是三个主要的前端框架,从市场占有量来看React,Vue.js算是并驾齐驱,Angular则要明显少于前两者,好像阿三程序员用的比较多。三者的基本介绍可以看这个:React、Angular、Vue.js:三者完整的比较指南。在Vue的中文官方网站上还有vue与React和Angular的详细对比:Vue对比其它框架。关于各个框架的介绍我就不多说了,网上很多博文有详细分析,我目前主要学习React,所以只写了React方面的东西,这里贴一下React的中文官方网站,大家可以详细的了解。
2.准备工作
2.1 安装Node.js
下载链接在此:下载
选择左边的稳定版即可。安装过程很简单,一直下一步,没有什么需要配置的东西。
要确定是否下载成功可以进入命令行(Win+R键,然后输入cmd进入),输入:node --v 显示出正确的版本即可。
2.2 创建工程
在创建工程之前,你可以参考React官网的快速体验:一分钟用上 React ,这个体验是直接在HTML文档中加入React组件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Add React in One Minute</title>
</head>
<body>
<h2>Add React in One Minute</h2>
<p>This page demonstrates using React with no build tooling.</p>
<p>React is loaded as a script tag.</p>
<!-- We will put our React component inside this div. -->
<div id="like_button_container"></div>
<!-- Load React. -->
<!-- Note: when deploying, replace "development.js" with "production.min.js". -->
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<!-- Load our React component. -->
<script src="like_button.js"></script>
</body>
</html>
'use strict';
const e = React.createElement;
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = { liked: false };
}
render() {
if (this.state.liked) {
return 'You liked this.';
}
return e(
'button',
{ onClick: () => this.setState({ liked: true }) },
'Like'
);
}
}
const domContainer = document.querySelector('#like_button_container');
ReactDOM.render(e(LikeButton), domContainer);
这个只是让你能快速的体验,在实际学习中,官方也不建议这么做。
- 如果你是在学习 React 或创建一个新的单页应用,请使用 Create React App。
- 如果你是在用 Node.js 构建服务端渲染的网站,试试 Next.js。
- 如果你是在构建面向内容的静态网站,试试 Gatsby。
- 如果你是在打造组件库或将 React 集成到现有代码仓库,尝试更灵活的工具链。
前面已经安装好的了Node.js,所以创建一个单页应用很简单,新建一个文件夹,这个文件夹用于存放你生存的应用。在文件夹目录下打开你的命令行,然后输入下面的命令:
npx create-react-app my-app
cd my-app
npm start
其实点击上面蓝色的“Create React APP”就可以跳转到创建应用的官方文档,这里也不赘述。
2.3 用VSCode 打开my-app文件夹
这里我直接推荐使用VScode打开,当然你也可以用WebStorm之类的软件。文件夹结构如下:
my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── serviceWorker.js
要重点关注的是:
public/index.html
是页面模板;src/index.js
是 JavaScript 入口点。
对于要构建的项目,上面的文件必须以确切的文件名存在。其中index.js又引入了App.js.
你可以在 src
中创建子目录。 为了加快重新构建的速度,Webpack 只处理 src
中的文件。 你需要将任何 JS 和 CSS 文件放在 src
中,否则 Webpack 将发现不了它们。
2.4 运行项目
进入你创建的my-app文件夹,打开命令行,输入:npm start即可启动应用程序。
npm start
在开发模式下运行应用程序。打开 http://localhost:3000 以在浏览器中查看它。
如果你进行编辑,页面将重新加载。你还将在控制台中看到任何 lint 错误。
npm test
以交互式监视模式启动测试运行器。有关更多信息,请参阅有关 运行测试 的部分。
npm run build
将生产应用程序构建到 build
文件夹。它能将 React 正确地打包为生产模式中并优化构建以获得最佳性能。
构建将被压缩,文件名中将包含哈希。有关更多信息,请参阅 生产构建 部分。
这样你的应用已准备好部署了。有关将应用程序部署到服务器的详细信息,请参阅有关 部署 的部分。
npm run eject
注意:这是单向操作。一旦你 eject
,你就不能回去了!
如果你对构建工具和配置选项不满意,可以随时 eject
。此命令将从项目中删除单个构建依赖项。
本节的详细内容可以参考:Create React App中文文档
3. JSX表达式和React基本理念
3.1 JSX 的基本结构
因为官网的介绍简明扼要,所以这里基本上是复制一遍,加深记忆。
下面声明了一个name变量,然后再JSX中使用它,并将它包裹在大括号中:
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;
ReactDOM.render(
element,
document.getElementById('root')
);
在 JSX 语法中,你可以在大括号内放置任何有效的 JavaScript 表达式。例如,2 + 2
,user.firstName
或 formatName(user)
都是有效的 JavaScript 表达式。例子如下:
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Harper',
lastName: 'Perez'
};
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
ReactDOM.render(
element,
document.getElementById('root')
);
ReactDOM.render函数可以直接对包含JSX表达式的变量进行渲染。该函数的第一个参数为要渲染的对象,第二个参数为对象插入的节点位置。
3.2 JSX的运行原理
JSX也是一个表达式,在编译之后会被转为普通的JavaScript函数调用,并且对其取值后得到JavaScript对象。
Babel 会把 JSX 转译成一个名为 React.createElement()
函数调用。
以下两种示例代码完全等效:
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
React.createElement()
会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象:
// 注意:这是简化过的结构
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
这些对象被称为 “React 元素”。它们描述了你希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建 DOM 以及保持随时更新。
可以看到使用JSX不仅可以少写代码,从形式上也更容易理解JSX的设计理念。
3.3 JSX的基本语法
你可以在 if
语句和 for
循环的代码块中使用 JSX,将 JSX 赋值给变量,把 JSX 当作参数传入,以及从函数中返回 JSX:
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
你可以通过使用引号,来将属性值指定为字符串字面量:
const element = <div tabIndex="0"></div>;
也可以使用大括号,来在属性值中插入一个 JavaScript 表达式,在属性中嵌入 JavaScript 表达式时,不要在大括号外面加上引号。你应该仅使用引号(对于字符串值)或大括号(对于表达式)中的一个,对于同一属性不能同时使用这两种符号。
在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。以下实例中如果变量 i 等于 1 浏览器将输出 true, 如果修改 i 的值,则会输出 false.
ReactDOM.render(
<div>
<h1>{i == 1 ? 'True!' : 'False'}</h1>
</div>
,
document.getElementById('example')
);
警告:
因为 JSX 语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase
(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。
DOM 元素的属性是标准规范属性,但有两个例外——class 和 for,这是因为在 JavaScript 中这两个单词都是关键字。因此,我们要将class属性改为className,for 属性改为HTMLFor。
例如,JSX 里的 class
变成了 className
,而 tabindex
则变为 tabIndex
。
使用 JSX 指定子元素
假如一个标签里面没有内容,你可以使用 />
来闭合标签,就像 XML 语法一样:
const element = <img src={user.avatarUrl} />;
JSX 标签里能够包含很多子元素:
const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);
3.4 JSX 防止注入攻击
你可以安全地在 JSX 当中插入用户输入内容:
const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;
React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。
3.5 JSX中使用样式
React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式:
var myStyle = {
fontSize: 100,
color: '#FF0000'
};
ReactDOM.render(
<h1 style = {myStyle}>菜鸟教程</h1>,
document.getElementById('example')
);
通过内联方式添加样式时要注意:下面是错误的
ReactDOM.render(
<h1 style = {fontSize:12}>菜鸟教程</h1>,
document.getElementById('example')
);
正确的写法是:
ReactDOM.render(
<h1 style = {{fontSize:12}}>菜鸟教程</h1>,
document.getElementById('example')
);
3.6 JSX添加注释
JSX的注释需要写在花括号中,实例如下:
ReactDOM.render(
<div>
<h1>菜鸟教程</h1>
{/*注释...*/}
</div>,
document.getElementById('example')
);
需要说明的是:
1、在标签内部的注释需要花括号
2、在标签外的的注释不能使用花括号
如下面的例子:
ReactDOM.render(
/*注释 */
<h1>孙朝阳 {/*注释*/}</h1>,
document.getElementById('example')
);
3.7 React使用JSX的理念
首先,JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。
React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合,比如,在 UI 中需要绑定处理事件、在某些时刻状态发生变化时需要通知到 UI,以及需要在 UI 中展示准备好的数据。
React 并没有采用将标记与逻辑进行分离到不同文件这种人为地分离方式,而是通过将二者共同存放在称之为“组件”的松散耦合单元之中,来实现关注点分离。
4. React元素渲染和更新
4.1 元素渲染
元素是构成React应用的最小砖块
元素描述了你在屏幕上想看到的内容
如:
const element = <h1>Hello, world</h1>;
与浏览器的 DOM 元素不同,React 元素是创建开销极小的普通对象。React DOM 会负责更新 DOM 来与 React 元素保持一致。
假设你的 HTML 文件某处有一个 <div>
:
<div id="root"></div>
我们将其称为“根” DOM 节点,因为该节点内的所有内容都将由 React DOM 管理。
仅使用 React 构建的应用通常只有单一的根 DOM 节点。如果你在将 React 集成进一个已有应用,那么你可以在应用中包含任意多的独立根 DOM 节点。
想要将一个 React 元素渲染到根 DOM 节点中,只需把它们一起传入 ReactDOM.render()
:
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
4.2 元素更新
React 元素是不可变对象。一旦被创建,你就无法更改它的子元素或者属性。一个元素就像电影的单帧:它代表了某个特定时刻的 UI。
根据我们已有的知识,更新 UI 唯一的方式是创建一个全新的元素,并将其传入 ReactDOM.render()
。
考虑一个计时器的例子:
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(element, document.getElementById('root'));
}
setInterval(tick, 1000);
这个例子会在 setInterval()
回调函数,每秒都调用 ReactDOM.render()
。其中setInterval的第一个参数是要运行的函数,第二参数是时间间隔(单位是毫秒)。
React 只更新它需要更新的部分
React DOM 会将元素和它的子元素与它们之前的状态进行比较,并只会进行必要的更新来使 DOM 达到预期的状态。
运行上面的例子你会发现只有时间是变化的,浏览器并没有刷新整个页面,这是很高效的渲染方式。
5. React中的函数(组件)和参数(props)
组件允许你将 UI 拆分为独立可复用的代码片段,并对每个片段进行独立构思。
组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。
5.1 函数组件和class组件
定义组件最简单的方式就是编写 JavaScript 函数:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
该函数是一个有效的 React 组件,因为它接收唯一带有数据的 “props”(代表属性)对象与并返回一个 React 元素。这类组件被称为“函数组件”,因为它本质上就是 JavaScript 函数。
你同时还可以使用 ES6 的 class 来定义组件:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
上面两个组件在React里是等效的。
5.2 组件渲染
在前面,我们介绍的都是DOM标签,React元素也可以是用户自定义组件:
const element = <Welcome name="Sara" />;
当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)转换为单个对象传递给组件,这个对象被称之为 “props”。
例如,这段代码会在页面上渲染 “Hello, Sara”:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
- 我们调用
ReactDOM.render()
函数,并传入<Welcome name="Sara" />
作为参数。 - React 调用
Welcome
组件,并将{name: 'Sara'}
作为 props 传入。 Welcome
组件将<h1>Hello, Sara</h1>
元素作为返回值。- React DOM 将 DOM 高效地更新为
<h1>Hello, Sara</h1>
。
注意: 组件名称必须以大写字母开头。
React 会将以小写字母开头的组件视为原生 DOM 标签。例如,<div />
代表 HTML 的 div 标签,而 <Welcome />
则代表一个组件,并且需在作用域内使用 Welcome
。
5.3 组合组件
组件可以在其输出中引用其他组件。这就可以让我们用同一组件来抽象出任意层次的细节。按钮,表单,对话框,甚至整个屏幕的内容:在 React 应用程序中,这些通常都会以组件的形式表示。
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
通常来说,每个新的 React 应用程序的顶层组件都是 App
组件。但是,如果你将 React 集成到现有的应用程序中,你可能需要使用像 Button
这样的小组件,并自下而上地将这类组件逐步应用到视图层的每一处。
5.4 参数的不变性
组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。
对参数不做修改的函数成为纯函数,如下面的求和函数:
function sum(a, b) {
return a + b;
}
这个函数不会参数更改参数,且多次调用相同的参数返回相同的结果。
相反,如果函数对参数进行修改,那么就是不纯函数:
function withdraw(account, amount) {
account.total -= amount;
}
React非常灵活,但是它也一个严格的规则:
所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。
来源:CSDN
作者:q__y__L
链接:https://blog.csdn.net/q__y__L/article/details/104654642