假设我们并不了解 node & npm 的情况下,使用最被大家熟知的方法:
脚本引入方式,来开始学习 react 框架。
官方文档:https://react.docschina.org/
管他三七二十一,先整一个项目再说:在你习惯放置学习代码的地方,建个目录(例:F:\wwwroot\react-demo),并建一个 demo01.html,搭好 html 5 格式:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, React!</h1>,
document.getElementById('main')
);
script>
body>
html>
依赖分析
react.development
: react 核心库,包含创建组件的类和函数,
react-dom.development
: 页面呈现库,包含 react 组件或元素在浏览器呈现的函数,主要是 render 函数
babel
: 代码转换库,可用于 react 的 jsx 语法转换,也可以用于 es6 语法的转换,这里不去深究 babel 的全部内容,只需看成一个工具即可
代码说明
先捋一捋 body 中包含了什么:
脚本语块很明显,ReactDOM 对象调用了 render 方法,实际上是将一段 html 标签,挂载到一个 dom 对象上,通常来说,js 将一段 html 标签挂载到一个 dom 上,是以字符串的格式塞到一个 dom 对象的 innerHTML 中,以以往的方式来看,有些麻烦:
var list = ['苹果', '香蕉', '橙子', '葡萄'],html = '', dom = document.getElementById('ul');
list.map(text => html += `${text}`);
dom.innerHTML = html; // typeof html => string
react 为了方便在 js 中能够直接插入 html 片段的方式,扩展了 js 的语法,而采用的 jsx 语法,完全是为了方便开发,jsx 通过 babel 的转换得到的就是普通的 js
转换前:
ReactDOM.render(
Hello, React!
,
document.getElementById('main')
);
转换后:
ReactDOM.render(
React.createElement('h1', null, 'Hello, React!'),
document.getElementById('main')
);
好了,你是否已经对 react 有所初步的了解啦,说白了,就跟之前引入 jquery、bootstrap 等库的引入方式一样啦~~~
按照官网的解释:react 是一个用于构建用户界面的 javascript 库,除了对库的引用,还需要了解 react 个人特性:
虚拟 DOM 的优势以及与真实 DOM 之间的对比
在 react 中,通常使用 “{}” 花括号对数据进行值的绑定,可以是字面量、也可以是变量,甚至是一个 HTML 标签组
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
ReactDOM.render(
<h1>{'Hello, React!'}</h1>,
document.getElementById('main')
);
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
let title = 'Hello, React!';
ReactDOM.render(
<h1>{title}</h1>,
document.getElementById('main')
);
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
let title = <span>Hello, React!</span>;
ReactDOM.render(
<h1>{title}</h1>,
document.getElementById('main')
);
script>
body>
html>
相较于界面交互,除了对节点内容数据进行值的绑定,也会有一些样式处理,或使用 javascript 逻辑语句使用:分支、遍历等操作
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
let style = { color: 'red' };
ReactDOM.render(
<h1 style={style}>Hello, React!</h1>,
document.getElementById('main')
);
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
ReactDOM.render(
<h1 style={{ color: 'red' }}>Hello, React!</h1>, // 需要注意:内层 "{}" 花括号是对象
document.getElementById('main')
);
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
ReactDOM.render(
<h1 className={'colorRed'}>Hello, React!</h1>, // 需要注意:class 是关键词,使用 className
document.getElementById('main')
);
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
let state = 1;
ReactDOM.render(
<h1 className={state === 1 ? 'colorRed' : 'colorBlue'}>Hello, React!</h1>,
document.getElementById('main')
);
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
let state = 1;
let html = '';
if(flag) {
html = <h2></h2>
} else {
html = <h2></h2>
}
ReactDOM.render(
<h1>{html}</h1>,
document.getElementById('main')
);
script>
body>
html>
在 react 渲染部分一般使用三目运算符进行 if-else 分支,但对 switch 或 if-else if-…-else 这种多分支逻辑性业务处理,不推荐多重三目运算符处理:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
let state = 1, html = null;
switch(state) {
case 0: html = <span>星期日</span>; break;
case 1: html = <span>星期一</span>; break;
case 2: html = <span>星期二</span>; break;
case 3: html = <span>星期三</span>; break;
case 4: html = <span>星期四</span>; break;
case 5: html = <span>星期五</span>; break;
case 6: html = <span>星期六</span>; break;
}
ReactDOM.render(
<h1>{html}</h1>,
document.getElementById('main')
);
script>
body>
html>
在进行列表数据渲染的时候,推荐绑定 key 值,能更好、更快的渲染列表某项变更而致使的页面数据刷新,提高界面刷新效率
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
let list = ['苹果', '香蕉', '橙子', '葡萄'];
ReactDOM.render(
<ul>{list.map((text,index) => <li key={index}>{text}</li>)}</ul>,
document.getElementById('main')
);
script>
body>
html>
jsx 归纳:遇到 “{}” 开始的代码以 js 方式执行脚本,遇到 “<>” 开始的代码以 html 方式解析
想象一下,如果有一个 “Huge Page” 需要我们开发的时候,首先我们需要将这个页面拆分成多个组件,分离成单独的 jsx 文件,通过引入这些组件文件,并组合使用,就可以更好的分发开发或后期维护,这也是前端开发所具备的一大设计模式 —— 组件化
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
class HeaderComponent extends React.Component {
render() {
return <header>i'm the Header</header>
}
}
class MainerComponent extends React.Component {
render() {
return <section>i'm the Mainer</section>
}
}
class FooterComponent extends React.Component {
render() {
return <footer>i'm the Footer</footer>
}
}
ReactDOM.render(
<div>
<HeaderComponent />
<MainerComponent />
<FooterComponent />
</div>,
document.getElementById('main')
);
script>
body>
html>
在 react 世界里,没有什么不是一个组件的问题,不管是你封装的一段 HTML + CSS + JS 代码块,还是单一的 JS 代码块,都可以看成是一个组件。
组件的定义:对数据和方法的简单封装;
组件的特征:高耦合、低内聚、逻辑分化、面向对象编程;
组件的作用:可复用,提高运行效率;简化编码,利于后期维护工作;
组件的组成:状态 state、属性 props、事件处理 function {refs};
组件的规则:首字母大写,驼峰式命名,不能重名和使用关 ES6 键词;
组件的使用:类似 HTML 标签使用,必须闭合规则;
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js">script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js">script>
head>
<body>
<div id="main">div>
<script type="text/babel">
function HeaderComponent() {
return <header>i'm the Header</header>;
}
function MainerComponent() {
return <header>i'm the Mainer</header>
}
function FooterComponent() {
return <header>i'm the Footer</header>
}
ReactDOM.render(
<div>
<HeaderComponent />
<MainerComponent />
<FooterComponent />
</div>,
document.getElementById('main')
);
script>
body>
html>
不难发现,在 react 内,声明的函数,其实也是一种组件,与上述通过 class 声明的组件不同,function 声明的组件仅仅用于渲染,是傀儡,只有你给什么,它执行什么,而 class 声明的组件不但能够进行数据渲染,还具备一定的状态 state 管理