React入门学习笔记

眉间皱痕 提交于 2020-03-05 21:04:54

目录

1.React框架的介绍

2.准备工作

2.1 安装Node.js

2.2 创建工程

2.3 用VSCode 打开my-app文件夹

2.4 运行项目

npm start

npm test

npm run build

npm run eject

3. JSX表达式和React基本理念

3.1 JSX 的基本结构 

3.2 JSX的运行原理

3.3 JSX的基本语法

3.4 JSX 防止注入攻击

3.5 JSX中使用样式

3.6 JSX添加注释

4. React元素渲染和更新

4.1 元素渲染

4.2 元素更新

5. React中的函数(组件)和参数(props)

5.1 函数组件和class组件

5.2 组件渲染

5.3 组合组件

5.4 参数的不变性


 


 


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 + 2user.firstNameformatName(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')
);

 

  1. 我们调用 ReactDOM.render() 函数,并传入 <Welcome name="Sara" /> 作为参数。
  2. React 调用 Welcome 组件,并将 {name: 'Sara'} 作为 props 传入。
  3. Welcome 组件将 <h1>Hello, Sara</h1> 元素作为返回值。
  4. 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 不被更改。

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!