React教程

简介: React 是一个用于构建用户界面的 JAVASCRIPT 库。 React 主要用于构建 UI,很多人认为 React 是 MVC 中的 V(视图)。 React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。 React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。

React特点: 1.声明式设计 −React采用声明范式,可以轻松描述应用。 2.高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。 3.灵活 −React可以与已知的库或框架很好地配合。 4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。 5.组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。 6.单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

1.React 第一个实例:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js">
</script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js">
</script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js">
</script>
</head>
<body>

<div id="example"></div>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
</script>

</body>
</html>

实例解析:

实例中我们引入了三个库: react.development.min.js 、react-dom.development.min.js 和 babel.min.js:
react.min.js - React 的核心库
react-dom.min.js - 提供与 DOM 相关的功能
babel.min.js - Babel 可以将 ES6 代码转为 ES5 代码,这样我们就能在目前不支持 ES6 浏览器上执行 React 代码。Babel 内嵌了对 JSX 的支持。通过将 Babel 和 babel-sublime 包(package)一同使用可以让源码的语法渲染上升到一个全新的水平。

代码语言:javascript
复制
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);

如果我们需要使用 JSX,则 <script> 标签的 type 属性需要设置为 text/babel。

一个React项目的文件目录如下:

代码语言:javascript
复制
my-app/
README.md
node_modules/
package.json
.gitignore
public/
favicon.ico
index.html
manifest.json // 指定了开始页面index.html,一切的开始都从这里开始,所以这个是代码执行的源头。
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg

尝试修改 src/App.js 文件代码:

代码语言:javascript
复制
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>欢迎来到世荣的博客</h2>
</div>
<p className="App-intro">
你可以在 <code>src/App.js</code> 文件中修改。
</p>
</div>
);
}
}

export default App;

测试过程中可能遇到的问题:
create-react-app 执行慢的解决方法:
在使用 create-react-app my-app 来创建一个新的React应用,在拉取各种资源时,往往会非常慢,一直卡在那:

代码语言:javascript
复制
fetchMetadata: sill mapToRegistry uri http://registry.npmjs.org/whatwg-fetc

可以看到资源还是使用了 npmjs.org,解决方法是换成淘宝的资源:

代码语言:javascript
复制
npm config set registry https://registry.npm.taobao.org
-- 配置后可通过下面方式来验证是否成功
npm config get registry
-- 或 npm info express

ReactDOM.render(...) 是渲染方法,所有的 js,html 都可通过它进行渲染绘制,他有两个参数,内容和渲染目标 js 对象。
内容就是要在渲染目标中显示的东西,可以是一个 React 部件,也可以是一段HTML或TEXT文本。渲染目标JS对象,就是一个DIV或TABEL,或TD 等HTML的节点对象。

代码语言:javascript
复制
ReactDOM.render(<App />, div);
unmountComponentAtNode() 这个方法是解除渲染挂载,作用和 render 刚好相反,也就清空一个渲染目标
中的 React 部件或 html 内容。

ReactDOM.unmountComponentAtNode(div);

2.React 元素渲染
元素是构成 React 应用的最小单位,它用于描述屏幕上输出的内容。

代码语言:javascript
复制
const element = <h1>Hello, world!</h1>;

与浏览器的 DOM 元素不同,React 当中的元素事实上是普通的对象,React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。
将元素渲染到 DOM 中
首先我们在一个 HTML 页面中添加一个 id="example" 的 <div>:

代码语言:javascript
复制
<div id="example"></div>

在此 div 中的所有内容都将由 React DOM 来管理,所以我们将其称为 "根" DOM 节点。
我们用 React 开发应用时一般只会定义一个根节点。但如果你是在一个已有的项目当中引入 React 的话,你可能会需要在不同的部分单独定义 React 根节点。
要将React元素渲染到根DOM节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:

代码语言:javascript
复制
实例
const element = <h1>Hello, world!</h1>;
ReactDOM.render(
element,
document.getElementById('example')
);

更新元素渲染
React 元素都是不可变的。当元素被创建之后,你是无法改变其内容或属性的。
目前更新界面的唯一办法是创建一个新的元素,然后将它传入 ReactDOM.render() 方法:
来看一下这个计时器的例子:

代码语言:javascript
复制
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>现在是 {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(
element,
document.getElementById('example')
);
}

setInterval(tick, 1000);

以上实例通过 setInterval() 方法,每秒钟调用一次 ReactDOM.render()。

我们可以将要展示的部分封装起来,以下实例用一个函数来表示:

代码语言:javascript
复制
function Clock(props) {
return (
<div>
<h1>Hello, world!</h1>
<h2>现在是 {props.date.toLocaleTimeString()}.</h2>
</div>
);
}

function tick() {
ReactDOM.render(
<Clock date={new Date()} />,
document.getElementById('example')
);
}

setInterval(tick, 1000);

React 只会更新必要的部分

值得注意的是 React DOM 首先会比较元素内容先后的不同,而在渲染过程中只会更新改变了的部分。

3.React JSX
React 使用 JSX 来替代常规的 JavaScript。
JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。
我们不需要一定使用 JSX,但它有以下优点:
JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
它是类型安全的,在编译过程中就能发现错误。
使用 JSX 编写模板更加简单快速。
我们先看下以下代码:

代码语言:javascript
复制
const element = <h1>Hello, world!</h1>;

这种看起来可能有些奇怪的标签语法既不是字符串也不是 HTML。
它被称为 JSX, 一种 JavaScript 的语法扩展。 我们推荐在 React 中使用 JSX 来描述用户界面。
JSX 是在 JavaScript 内部实现的。
我们知道元素是构成 React 应用的最小单位,JSX 就是用来声明 React 当中的元素。
与浏览器的 DOM 元素不同,React 当中的元素事实上是普通的对象,React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。
要将 React 元素渲染到根 DOM 节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:

代码语言:javascript
复制
React 实例
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));

由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。

使用 JSX
JSX 看起来类似 HTML ,我们可以看下实例:

代码语言:javascript
复制
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);

我们可以在以上代码中嵌套多个 HTML 标签,需要使用一个 div 元素包裹它,实例中的 p 元素添加了自定义属性 data-myattribute,添加自定义属性需要使用 data- 前缀。

代码语言:javascript
复制
ReactDOM.render(
<div>
<h1>世荣的博客</h1>
<h2>学习 React 记录史</h2>
<p data-myattribute = "somevalue">这是一个很不错的 JavaScript 库!</p>
</div>
,
document.getElementById('example')
);

独立文件
你的 React JSX 代码可以放在一个独立文件上,例如我们创建一个 helloworld_react.js 文件,代码如下:

代码语言:javascript
复制
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);

然后在 HTML 文件中引入该 JS 文件:
React 实例:

代码语言:javascript
复制
<body>
<div id="example"></div>
<script type="text/babel" src="helloworld_react.js"></script>
</body>

JavaScript 表达式
我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。实例如下:
React 实例

代码语言:javascript
复制
ReactDOM.render(
<div>
<h1>{1+1}</h1>
</div>
,
document.getElementById('example')
);

在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。以下实例中如果变量 i 等于 1 浏览器将输出 true, 如果修改 i 的值,则会输出 false.

代码语言:javascript
复制
React 实例
ReactDOM.render(
<div>
<h1>{i == 1 ? 'True!' : 'False'}</h1>
</div>
,
document.getElementById('example')
);

样式
React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式:
React 实例

代码语言:javascript
复制
var myStyle = {
fontSize: 100,
color: '#FF0000'
};
ReactDOM.render(
<h1 style = {myStyle}>世荣的博客</h1>,
document.getElementById('example')
);

注释
注释需要写在花括号中,实例如下:

代码语言:javascript
复制
React 实例
ReactDOM.render(
<div>
<h1>世荣的博客</h1>
{/注释.../}
</div>,
document.getElementById('example')
);

数组
JSX 允许在模板中插入数组,数组会自动展开所有成员:
React 实例

代码语言:javascript
复制
var arr = [
<h1>世荣的博客</h1>,
<h2>flag{welcome_to_my_home!}!</h2>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);

React 组件
如何使用组件使得我们的应用更容易来管理。
接下来我们封装一个输出 "Hello World!" 的组件,组件名为 HelloMessage:

React 实例

代码语言:javascript
复制
function HelloMessage(props) {
return <h1>Hello World!</h1>;
}

const element = <HelloMessage />;

ReactDOM.render(
element,
document.getElementById('example')
);

实例解析:
1.我们可以使用函数定义了一个组件:

代码语言:javascript
复制
function HelloMessage(props) {
return <h1>Hello World!</h1>;
}

也可以使用 ES6 class 来定义一个组件:

代码语言:javascript
复制
class Welcome extends React.Component {
render() {
return <h1>Hello World!</h1>;
}
}

2.const element = <HelloMessage /> 为用户自定义的组件。

注意,原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。

如果我们需要向组件传递参数,可以使用 this.props 对象,实例如下:

代码语言:javascript
复制
function HelloMessage(props) {
return <h1>Hello {props.name}!</h1>;
}

const element = <HelloMessage name="Runoob"/>;

ReactDOM.render(
element,
document.getElementById('example')
);

以上实例中 name 属性通过 props.name 来获取。

注意,在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。

复合组件
我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。

以下实例我们实现了输出网站名字和网址的组件:

代码语言:javascript
复制
function Name(props) {
return <h1>网站名称:{props.name}</h1>;
}
function Url(props) {
return <h1>网站地址:{props.url}</h1>;
}
function Nickname(props) {
return <h1>网站小名:{props.nickname}</h1>;
}
function App() {
return (
<div>
<Name name="世荣的博客" />
<Url url="https://www.shirong.ink" />
<Nickname nickname="世荣" />
</div>
);
}

ReactDOM.render(
<App />,
document.getElementById('example')
);