React 学习
基本介绍
A JavaScript library for building user interfaces —— React 是一个 JS 库,用来构建用户界面(再简单点就是写 HTML,构建 web 应用,这是指 PC 端,react 也可以用于很多别的地方) ,从 MVC 的角度来看,相当于 视图层 V(View) 的内容。
特点
- 声明式(Declarative)
- 你只需要描述 UI(HTML)看起来是什么样,就跟写 HTML 一样
- React 负责渲染 UI,并在数据变化时更新 UI
- 基于组件(Component-Based)
- 一次学习,随处使用(Learn Once, Write Anywhere) —— 可以用于手机端开发,也可以用于 VR
基本使用
- 安装包
npm i react react-dom
react 包是核心,提供创建元素、组件等功能,react-dom 包提供 DOM 相关功能等,同样的 react 还可以用于移动端,这时候就需要安装一个 react-native 这个包可以把创建的元素 渲染成移动端识别的元素
- 引入包
如果是直接在 html 页面中,那么就直接如下引入就行了(注意:引入顺序,react 在前,react-dom 在后)
<!-- 引入安装的包 注意引入包的顺序 -->
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
如果是在脚手架中,可以模块化的方式引入
import React from "react";
import ReactDOM from "react-dom";
- 创建元素
// 创建 react 元素,最简单的一个元素
const h1 = React.createElement("h1");
// createElement方法有三个参数
// 参数1:表示要创建什么元素,就是 HTML 标签名称
// 参数2:表示元素自身属性,如果没有就传 null,如果要指定元素自身的属性,就传递一个对象({}) class ==> className for ==> htmlFor
// 参数3:表示元素的子节点(文本、元素节点)
// 如果是文本节点,就直接传递 字符串。
// 如果是元素节点,就继续调用 React.createElement() 方法,创建新的React元素节点
const h1 = React.createElement("div", null, "Hello React");
const h1 = React.createElement(
"h1",
{
id: "title",
className: "cls",
htmlFor: "d"
},
"Hello React",
"test 文本节点",
React.createElement("span", null, "这是一个span")
);
- 渲染元素
// 渲染 react 元素
// 参数1:表示要渲染哪个元素
// 参数2:元素渲染到哪个位置去,这里可以使用各种获取DOM的方式
// 比如: document.querySelector("#root")
ReactDOM.render(h1, document.getElementById("root"));
Tips:上述这种方法很明显的在创建元素上显得很麻烦,因此这个我们作为了解就行了,后面我们会使用 react 的脚手架,在脚手架中使用 JSX 来创建 react 元素
React 脚手架
脚手架的意义
-
脚手架是开发 现代 Web 应用的必备。
-
充分利用 Webpack、Babel、ESLint 等工具辅助项目开发。
-
零配置,无需手动配置繁琐的工具即可使用。
-
关注业务,而不是工具配置。
脚手架的使用
- 安装包
# npm create-react-app 项目名称
npx create-react-app my-app
npx 命令介绍 —— 简化使用脚手架初始化项目的流程
npm v5.2.0 引入的一条命令
目的:提升包内提供的命令行工具的使用体验
原来:先安装脚手架包,再使用这个包中提供的命令
现在:无需安装脚手架包,就可以直接使用这个包提供的命令 (npx 命令执行的时候回临时帮我们把包下载到一个位置,然后执行包中的命令来帮我们创建脚手架,创建完成后会把这个包删除)
接下来的步骤就和上面的一样了,都是导入包 —> 创建 react 元素 —> 渲染 react 元素
JSX
JavaScript XML(HTML),也就是在 JS 中书写 HTMl 格式的代码
之前也说了用 react.createElement()
创建 react 元素的方式很繁琐、不直观并且效率不高,因此我们就可以用 JSX 来创建 react 元素,JSX 这语法浏览器是不识别的,是经过编译后才让浏览器运行的,中间经过了 @babel/preset-react
这个包的编译。
JSX 的基本使用
-
1 导入 react 和 react-dom
-
2 使用 JSX 语法创建 React 元素
-
JSX 就跟写 HTML 一样
-
3 渲染创建好的 React 元素
import React from "react";
import ReactDOM from "react-dom";
const h1 = <h1>hello react</h1>;
ReactDOM.render(h1, document.getElementById("root"));
JSX 语法的注意点
- JSX 元素的属性名推荐使用:驼峰命名法
- class ===> className
- 如果元素没有子节点,可以使用 单标签 方式来结束
- 比如:
<div />
- 比如:
- 推荐使用 () 来包裹 JSX,从而避免 JS 中自动插入分号机制
JSX 中使用 JavaScript 表达式
数据存储在 JS 中
语法:{ JavaScript 表达式 }
注意:语法中是单大括号,不是双大括号!
import React from "react";
import ReactDOM from "react-dom";
const name = "react";
const h1 = <h1>hello {
name}</h1>;
ReactDOM.render(h1, document.getElementById("root"));
注意
- 单大括号中可以使用任意的 JavaScript 表达式
- JSX 自身也是 JS 表达式
- 注意:JS 中的对象是一个例外,一般只会出现在 style 属性中
- 注意:不能在{}中出现语句(比如:if/for 等)
const span = <span>react</span>;
const h1 = <h1>hello {
span}</h1>;
ReactDOM.render(h1, document.getElementById("root"));
条件渲染
- 使用 if/esle 来实现
const loadData = () => {
if (isLoading) {
return <div>loading...</div>;
}
return <div>加载完成后的列表结构</div>;
};
const h1 = <div>{
loadData()}</div>;
- 使用三元表达式
const loadData = () => {
return isLoading ? <div>loading...</div> : <div>加载完成后的列表结构</div>;
};
- 逻辑运算符 &&
const loadData = () => {
return isLoading && <div>loading...</div>;
};
列表渲染
- 使用数组的 map 方法来进行列表渲染
- 需要给被遍历生成的元素添加 key 属性,key 应该是唯一的。尽量避免使用 index 作为索引号。
- 剩下的就是 JS 中 map 方法的使用了。
因为在 { } 中只能放表达式,因此 for 是不能使用的,因为这些是语句
const songs = [
{
id: 1, name: '痴心绝对' },
{
id: 2, name: '像我这样的人' },
{
id: 3, name: '南山南' }
]
<ul>
{
songs.map(item => (
<li key={
item.id}>{
item.name}</li>
))}
</ul>
这里为什么用一个 key 是为了让渲染的性能更好,如果使用过 Vue 的 v-for 指令的,应该可以理解这一块,两边是一样的。
添加样式
- 行内样式(style) 不推荐
const h1 = (
<h1 style={
{
color: "red", fontSize: 30, backgroundColor: "hotpink" }}>
我变大了
</h1>
);
- className 类名 — 推荐!!!
const h1 = <h1 className="pink">我变大了</h1>;
组件基础
函数组件
使用 JS 中的函数创建的组件,叫做函数组件
function Hello() {
return <h1>这是一个函数组件</h1>;
}
ReactDOM.render(<Hello />, document.getElementById("root"));
注意点:
- 函数必须有返回值
- 返回值可以为 null,表示不渲染任何内容
- 如果想要渲染内容,一般就是返回 JSX(比如上面)
- 组件名称必须以大写字母开头
- 用来区分普通的 react 元素 和 react 组件 (默认小写字母开头的都是 react 元素)
- 使用函数名称作为组件的标签名称来渲染
ReactDOM.render(<Hello />, root)
类组件(class)
通过 ES6 中的 class 创建的组件,叫做 类组件
函数组件中的注意点都适用于类组件,另外还有如下注意点
- 类组件必须得继承自 React.Component 父类
- 类组件中必须提供一个 render 方法,通过 render 方法的返回值来指定要渲染的内容
class Hello extends React.Component {
render() {
return <h1>这是一个类组件</h1>;
}
}
ReactDOM.render(<Hello />, document.getElementById("root"));
在将组件抽离到一个单独的 js 文件中的时候,不管是函数组件还是类组件,或者使用 JSX ,都需要导入 React!!!
import React from "react";
// 创建 class 组件
// class Hello1 extends React.Component {
// render() {
// return <div>这是一个独立的组件</div>
// }
// }
// 创建函数组件
// JSX -> React.createElement()
const Hello1 = () => <div>这是一个独立的组件</div>;
// 导出组件
export default Hello1;
哪里需要使用到这个组价可以直接导入就行
import Hello1 from 文件路径
事件处理
- React 事件绑定语法与 DOM 事件语法相似
- 语法:on+事件名称={事件处理程序},比如:onClick={() => {}}
- 注意:React 事件采用驼峰命名法,比如:onMouseEnter、onFocus
函数组件中使用
在函数组件中使用事件对象,可以在事件处理程序中用 一个形参 e 来接受
// function handleClick() {
// console.log('click')
// }
const handleClick = () => console.log('click')
// const handleClick = (e) => console.log(e)
function Hello() {
return (
<button onClick={
handleClick}>点我呀</button>
<button onClick={
() => console.log('click')}>点我呀</button>
)
}
类组件中使用
在类组件中使用事件对象,可以在事件处理程序中用 一个形参 e 来接受
class Hello extends React.Component {
handleClick(e) {
console.log("click");
console.log(e);
}
render() {
return <button onClick={
this.handleClick}>点我呀</button>;
}
}
事件对象注意点
- React 中的事件对象是一个 合成事件。
- 合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题
- 使用方式,与原生 DOM 中的使用方式相同。
有状态组件和无状态组件
- 有状态组件:class(类)组件
- 职责(什么时候使用):负责更新 UI(页面),也就是如果页面中的内容,需要变化
- 状态(state)即数据
- 无状态组件:函数组件
- 职责:负责展示内容
State 和 setState
状态(state)即数据,是组件内部的私有数据,只能在组件内部使用,state 的值是对象,表示一个组件中可以有多个数据
初始化状态
class Hello extends React.Component {
constructor() {
super();
// 状态初始化
this.state = {
count: 0
};
}
// 简化语法:
// state = {
// count: 66
// }
// 在 JSX 中使用状态
render() {
return <div>计数器:{
this.state.count}</div>;
}
}
setState()修改状态
- 状态是可变的
- 语法:this.setState({ 要修改的数据 })
- 注意:不要直接修改 state 中的值,这是错误的!!!
- this.state.count = 66 这样是错误的
- setState() 作用:1. 修改 state 2. 更新 UI
- 思想:数据驱动视图
下面是一个点击按钮后让数字 +1 的例子
class Hello extends React.Component {
state = {
count: 0
};
render() {
return (
<div>
<span>{
this.state.count}<