1、基本应用(传统应用):在页面文件中导入React的核心库(.js文件),可以引入官网上的地址,也可以自己下载之后本地引入。
(1)核心库:react.development.js
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin>script>
<script src="../react的js库/react.development.js">script>
(2)与DOM相关的库:react-dom.development.js
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin>script>
<script src="../react的js库/react-dom.development.js">script>
(3)babel编译器库:将ES6转换成ES5
<script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
<script src="../react的js库/babel.min.js">script>
2、脚手架开发:搭建React项目,根据不同的需求开发组件
(1)create-react-app:属于FacdBook,快速的、不做任何配置的构建React开发环境
npm install -g create-react-app
(2)create-react-app构建的react开发环境是基于webpack+ES6
首先引入库文件:
<script src="../react的js库/react.development.js">script>
<script src="../react的js库/react-dom.development.js">script>
<script src="../react的js库/babel.min.js">script>
在body标签中编写JavaScript代码:
<div id="example">div>
<script type="text/babel">
ReactDOM.render(
<h1>Hello World</h1>,
document.getElementById("example")
)
script>
React框架的核心优势之一, 就是支持创建虚拟DOM来提高页面性能。那么,什么是虚拟DOM呢?其实, 虚拟DOM这个概念很早就被提出来了, 是相对于实际DOM而言的。
设计人员在设计传统HTML网页的UI时, 都会在页面中定义若干的DOM元素, 这些DOM元素是所谓的实际DOM。通常, 页面中的实际DOM负责承载着外观表现和数据变化,任何外观形式的改变或数据信息的更新都要反馈到UI上, 都是需要通过操作实际DOM来实现的。
于是, 问题也就自然出现了。对于复杂的页面UI而言, 往往会定义大量的实际DOM。频繁地操作大量实际DOM, 往往会带来访问性能的严重下降, 用户体验也会随之变差, 这些都是设计人员所不希望看到的。因此, React框架专门针对这个现象引入了虚拟DOM机制,以避免频繁的DOM操作带来的性能下降问题。
React DOM类似于一种将相关的实际DOM组合在一起的集合, 是React的虚拟DOM对象,内置对象,将其理解为DOM组件应该更为贴切。因此,React框架将ReactDOM称为虚拟DOM。
示例代码:传统的(实际)DOM
<div id="app">div>
<script>
// 获取页面中的div
let div = document.getElementById("app");
// 创建span标签
let span = document.createElement("span");
// 创建h3标签
let h3 = document.createElement("h3");
h3.innerHTML = "橘猫吃不胖";
// 创建p标签
let p = document.createElement("p");
p.innerHTML = "新年快乐";
// 将h3和p都添加到span中
span.appendChild(h3);
span.appendChild(p);
// 将span添加到div中
div.appendChild(span);
script>
示例代码:虚拟DOM
<div id="react-div">div>
<script type="text/babel">
let reactDiv = document.getElementById("react-div");
//创建虚拟的DOM元素
//React.createElement中3个参数表示元素名字,空对象以及对象中的内容
const reactH3 = React.createElement("h3", {}, "橘猫吃不胖");
const reactP = React.createElement("p", {}, "新年快乐");
const reactSpan = React.createElement("span", {}, reactH3, reactP);
//将span渲染到div中去
ReactDOM.render(reactSpan, reactDiv);
script>
render函数:渲染函数,将react的虚拟DOM元素渲染到页面中
ReactDOM.render(element,container[,callback])
element参数:必须,表示渲染的源对象(元素或组件)
container参数:必须,表示渲染的目标对象(元素或组件)
callback参数:可选,用于定义回调函数
React框架之所以大受欢迎, 其特有的渲染机制是非常重要的因素之一。既然提到React 渲染机制, 那么就说一说Diff算法, 该算法是支撑React渲染机制的核心技术之一。
Diff算法的核心就是扫描DOM树,通过扫描找到DOM树前后的差异。若DOM树的状态或属性发生改变,React会构建新的DOM树,将新的DOM树和原来的DOM树进行比较,找到树中变化的部分进行修改。好处是避免重复的频繁的操作DOM,提高页面的访问性能。
声明式设计:React 采用声明范式,可以轻松描述应用。
高效:React通过对DOM的模拟,最大限度地减少与DOM的交互。
灵活:React可以与已知的库或框架很好地配合。
使用JSX语法:JSX是JavaScript语法的扩展,可以极大地提高JS运行效率。
组件复用:通过React构建组件使得代码易于复用,可在大型项目应用开发中发挥优势。
单向响应的数据流:React实现了单向响应的数据流,减少了重复代码,比传统数据绑定方式更简单。
create-react-app 是来自于Facebook,通过该命令我们无需配置就能快速构建 React 开发环境。create-react-app 自动创建的项目是基于 Webpack + ES6 。
安装create-react-app
npm install -g create-react-app
创建项目
create-react-app my-app
进入项目所在目录
cd my-app
启动项目
npm start
JSX是JavaScript XML的缩写,是JavaScript的语法的扩展,支持自定义属性,是react的内置的语法,其基本语法格式为
const 元素名 = (
<根标签名>
<子标签></子标签>
</根标签名>
);
注意:
(1)创建元素时必须有一个根标签,该根标签是一个容器,里面可以包含其他的标签
(2)在react的脚手架项目中可以使用空标签(<>>)作为根标签
若要在React项目中使用JSX语法, 则必须引用“babel.js”来解析JSX,且在标签中必须改用
type="text/ babel"
属性。原因是: 在使用type="text/babel"
属性替换type="text/javascript
属性后, 浏览器内置的JavaScript解释器就不会解析标签里的脚本代码, 转而由“babel.js”进行解析, 从而避免React代码与原生JavaScript代码发生混淆。
示例代码:
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
const span = (
<span>
<h3>React JSX</h3>
<p>通过jsx语法创建一个元素</p>
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
在React JSX中使用JavaScript表达式要使用大括号”{ }”括起来,可以解析算术表达式。在{}中放算术表达式即可。
示例代码:
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
const span = (
<span>
<h3>JSX算术表达式</h3>
<p>3+6 = {3 + 6}</p>
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
在React JSX中使用JavaScript表达式无法使用if条件语句,但是可以使用条件运算符构成
条件表达式来替代if条件语句
示例代码:
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
const span = (
<span>
<h3>JSX条件表达式</h3>
<p>1==1:{1 == 1 ? "true" : "false"}</p>
<p>1!==1:{1 !== 1 ? "true" : "false"}</p>
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
先定义一个变量,可以通过在JSX中引用该变量的方式使用该变量
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
let name = "橘猫吃不胖";
const span = (
<span>
<h3>JSX嵌入表达式</h3>
<p>用户名:{name}</p>
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
在{}中可以直接以“对象名.属性”方式访问对象
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
let user = {
name: "橘猫吃不胖",
age: 10
}
const span = (
<span>
<h3>JSX对象表达式</h3>
<p>姓名:{user.name}</p>
<p>年龄:{user.age}</p>
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
可以通过函数的调用来实现对if的使用
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
function userInfo() {
return "橘猫吃不胖";
}
const span = (
<span>
<h3>JSX函数表达式</h3>
<p>{userInfo()}</p>
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
function userInfo(msg) {
if (msg) {
return msg;
} else {
return "信息为空";
}
}
const span = (
<span>
<h3>JSX增强函数表达式</h3>
<p>{userInfo("橘猫吃不胖")}</p>
<p>{userInfo()}</p>
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
在数组中存放标签,在{}中解析数组
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
let arr = [
<p>姓名:橘猫吃不胖</p>,
<p>年龄:10</p>
]
const span = (
<span>
<h3>JSX数组表达式</h3>
<p>{arr}</p>
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
将CSS样式应用到虚拟DOM中
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
let css1 = {
color: "red"
}
let css2 = {
color: "orange"
}
const span = (
<span>
<h3>JSX样式表达式</h3>
<p style={css1}>AAAA</p>
<p style={css2}>BBBB</p>
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
在JSX元素中(虚拟DOM)中进行注释,使用的格式是{/*注释内容*/}
。
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
const span = (
<span>
<h3>JSX注释表达式</h3>
{/*这是一行注释*/}
</span>
)
// 将span添加到root中
ReactDOM.render(span, root);
script>
React组件可以将UI切分成一些独立的、可复用的部件, 这样有助于设计人员专注于构建每一个单独的部件。React组件通过Props可以接收任意的输入值, 因此Props也可以理解为参数的概念。
React语法是基于版本ECMAScript6实现的。因此,React组件除了通过JavaScript函数形式实现,还可以通过ES6 Class(类)的形式来实现。
函数组件是基于ES6的函数,是轻量级组件(不占用内存空间),React官方提倡使用。
语法为:
// 组件的名称的首字母必须要大写
function Fun() {
return (
<标签></标签>
)
}
使用函数组件时,要将函数名当做标签使用:
<Fun />
示例:在页面上输出Hello World!
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
function SayHello() {
return <p>Hello World!</p>
}
ReactDOM.render(<SayHello />, root);
script>
语法为:
class 类名 extends React.Component {
render() {
return <标签></标签>
}
}
使用:将类名当做标签名使用
<类名 />
强调:无论是函数组件还是类组件,组件名的首字母必须大写
类组件示例代码:
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
class Hello extends React.Component {
render() {
return <p>Hello~</p>
}
}
ReactDOM.render(<Hello />, root);
script>
示例代码:
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
//创建函数组件
function FormTitle() { // 标题组件
return (
<h3>用户登录</h3>
)
}
function UserId() {
return UserId = (
<p>用户ID:<input type="text" /></p>
)
}
function UserName() {
const userName = (
<p>用户名:<input type="text" /></p>
)
return userName;
}
function UserPwd() {
const userPwd = (
<p>密码:<input type="password" /></p>
)
return userPwd;
}
function Submit() {
return (
<button>登录</button>
)
}
// 将函数组件组合成一个组件
function FormLogin() {
return (
<div>
<FormTitle />
<UserId />
<UserName />
<UserPwd />
<Submit />
</div>
)
}
// 渲染
ReactDOM.render(<FormLogin />, root);
script>
React框架定义了一个Props的概念, 专门用来实现React函数组件接收参数。
示例代码:
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
function Hello(props) {
return <p>你好,{props.name}</p>
}
ReactDOM.render(<Hello name="橘猫吃不胖"/>, root);
script>
示例:通过props初始化表单
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
function UserId(props) {
const userId = (
<p>用户名:<input type="text" value={props.userId} /></p>
)
return userId;
}
ReactDOM.render(<UserId userId="1001" />, root);
script>
注意:
(1)在使用函数组件时无论是否传递参数,props属性都是默认存在的
(2)props的参数值是只读的,不能修改,因此上述示例中的input标签中的1001不可以修改
(3)在类组件中可以使用props属性的defaultProps来设置组件的默认值(标签可以设置defaultValue属性,该属性的值可以是Props属性的值),具体方法为:
类名.defaultProps = {
属性名: 默认值
}
或者可以使用static来定义默认值,示例代码如下:
static.defaultProps = {
属性名: 默认值
}
(4)在函数组件中使用props属性的defaultProps来设置组件的默认值
函数名.defaultProps = {
属性名: 默认值
}
使用标签的defaultValue属性默认值就可以修改上面的input中的内容不可以修改的问题了,示例代码如下:
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
function UserId(props) {
const userId = (
<p>用户名:<input type="text" defaultValue={props.userId} /></p>
)
return userId;
}
ReactDOM.render(<UserId userId="1001" />, root);
script>
(5)可以通过Props对虚拟DOM中的标签属性进行类型、必要性的限制
第一步:导入prop-types.js库文件:对props属性进行类型、必要性的检查
<script src="../react的js库/prop-types.js">script>
第二步:通过PropTypes对标签属性进行限制
第三步:在函数组件中进行类型检查
函数名.propTypes = {
属性名: PropTypes.类型名.必要性限制
}
在类中进行类型检查步骤:①在类的内部使用static进行定义
static propTypes = {
属性名: PropTypes.类型名.必要性限制
}
②在类的外部进行定义
类名.propTypes = {
属性名: PropTypes.类型名.必要性限制
}
示例代码:在类中进行类型检查
<div id="root">div>
<script type="text/babel">
let root = document.getElementById("root");
class PropsTest extends React.Component {
static defaultProps = {
name: "张三",
age: 33,
address: "北京"
}
static propTypes = {
name: PropTypes.string.isRequired, // 表示name属性值必须是string类型,并且不能缺少
address: PropTypes.string,
age: PropTypes.number
}
constructor(props) {
super(props);
}
render() {
const { name, age, address } = this.props
return (
<div>
<label>用户名:
<input type="text" defaultValue={name} />
</label>
<br />
<label>年龄:
<input type="text" defaultValue={age} />
</label>
<br />
<label>用户名:
<input type="text" defaultValue={address} />
</label>
<br />
</div>
)
}
}
ReactDOM.render(<PropsTest />, root)
script>