React是用于构建用户界面的JavaScript库, 起源于Facebook的内部项目,该公司对市场上所有 JavaScript MVC框架都不满意,决定自行开发一套,用于架设Instagram的网站。于2013年5月开源
一、React简介
React以声明式编写 UI,可以让代码更加可靠,且方便调试;创建拥有各自状态的组件,再由这些组件构成更加复杂的 UI。
CS 与 BS结合:像 React,Vue 此类框架,转移了部分服务器的功能到客户端。将CS 和 BS 加以结合。客户端只用请求一次服务器,服务器就将所有js代码返回给客户端,所有交互类操作都不再依赖服务器。 客户端只有在需要服务器的数据时才会使用json通信一下,其他时间都在客户端利用js操作、暂存数据这样就极大减轻了服务器压力。
1.1 React特点
1. 声明式变成
React 使创建交互式 UI 变得轻而易举。为应用的每一个状态设计简洁的视图,当数据改变时 React 能有效地更新并正确地渲染组件。
2. 组件化思维
组件逻辑使用 JavaScript 编写而非模板,因此可以轻松地在应用中传递数据,并使得状态与 DOM 分离。
3. 编写方便
无论你现在正在使用什么技术栈,你都可以随时引入 React 来开发新特性,而不需要重写现有代码。React 还可以使用 Node 进行服务器渲染,或使用 React Native 开发原生移动应用。
1.2 JXL语法
为了构建交互式用户界面,使用了 JSX。JSX 的完整版本是一个JavaScript语法扩展,它极大地简化了组件的创建。它支持HTML引用并使子组件渲染更容易。它本质上是一组 React 编写快捷方式。使用带有一些规则的 createElement 可以使源代码更具可读性和直接性。首先写jsx文件,运行时会先将所编写的jsx编译为js,编译完之后,将js文件运行在浏览器。
二、安装并创建项目
在使用React之前,先确保你已经安装了node.js,后续过程都是在node环境下运行的。使用window+R,输入cmd,回车。
1. npm i -g create-react-app 安装React
2. creat-react-app 项目名称(myreact) 创建项目
3. cd /myreact 进入到项目
4. npm start 运行项目
三、项目文件结构
四、React语法
4.1 JSX语法
html与js混写的语法 JavaScript和XML的混写,需要编译器编译才能被浏览器执行。特点js书写html模板方便;比较接近原生,编译较快。
1. {}写js表达式;
2. {/*注释内容 */} 注释;
3. 数组里面可以包含html标签;
4. 类似于vue2,有且仅有一个根节点;
5. 类名要用className;
6. 样式style会自动展开。
具体代码如下:
App.js
import './App.css'
const styles = {
fontSize: "48px",
color: "#770",
fontWeight: 900
}
function App() {
var msg = "中国香港是他主持回归的";
var list = [
<h2>A</h2>,
<h2>B</h2>,
<h2>C</h2>
]
return (<div>
<h1 className="active">你好,react</h1>
<p style={styles}>{msg}</p>
{/* <p>{8 > 5 ? "可大了" : "太小了"}</p> */}
{list}
</div>)
}
export default App;
App.css
.active {
color: #f70;
}
4.2 内容渲染
1. 文本渲染:将内容直接写在{}内;内容中如果包含html标签也可以被渲染,需要添加dangerouslySetInnerHTML。
function App() {
let msg = "你好中国react!"
let text = "2023年还有<strong>一个月</strong>就到了"
return (
<div>
<h1>模板语法</h1>
<h2>文本渲染</h2>
<p>{msg}</p>
<p dangerouslySetInnerHTML={{ __html: text }}></p>
</div>
)
}
export default App;
2. 列表渲染: 通过map映射来渲染,如果是字符串,可以先通过split分割成数据再渲染。
function App() {
let msg = "你好中国react!"
let list = ["vue", "react", "uni-app", "小程序"]
return (
<div>
<h1>模板语法</h1>
<h2>列表渲染</h2>
{
list.map((item, index) => <h4 key={index}>{item}</h4>)
}
<div>
{msg.split("").map((item, ind) => <p key={ind}>{item}</p>)}
</div>
</div>
)
}
export default App;
3. 条件渲染:有两种方式,使用三元运算符进行判断;使用&&来判断。
function App() {
let flag = true
let isLog = true
return (
<div>
<h1>模板语法</h1>
<h2>条件渲染</h2>
{flag ? <p>成功</p> : <p>失败</p>}
{isLog && <p>欢迎回来</p>}
</div>
)
}
export default App
4.3 事件响应函数
事件响应有两种方式:使用箭头函数onClick={()=>{相应内容}};使用this, onClick={this.say},say为自定义函数。
函数传参也有两种方式:匿名函数 onClick={()=>this.say(参数)}或者onClick={this.say.bind(this,参数)}。
4.4 组件
1. 函数组件:负责展示,也称为视图组件。
function Demo() {
return ( );
}
export default Demo;
2. 类组件:负责处理数据,也称为容器组件。类组件包含state、生命周期、props、this等。
class Demo extends Component {
constructor(props) {
super(props);
}
state = { }
render() {
return ( );
}
}
export default Demo;
4.5 组件传参
1.父组件向子组件传参,通过props属性方式。
2. 子组件向父组件传参,通过props回调函数方式。
3. 默认props及唯一的插槽
五、React生命周期
React组件在从创建到销毁会经历一系列过程,在这些过程执行回调函数,称为生命周期钩子函数。React的生命周期仅存在与类组件中;函数组件中没有生命周期的概念,但可以使用Hooks模拟生命周期。
5.1 挂载
1. constructor:初始化state;
2. static getDerivedStateFromProps:props更新触发state更新(要求返回一个新的state) nextProps最新的props;
3. render渲染;
4. componentDidMount(重要) 组件已经挂载;作用:监听事件、开启定时器、ajax请求,dom操作。
import React, { Component } from 'react';
class Life extends Component {
constructor(props) {
super(props);
console.log("挂载-01-constructor")
}
static getDerivedStateFromProps(nextProps, prevState) {
//当props发送变化时候更新state
console.log("挂载-02-getDerivedStateFromProps");
return ({})
}
state = { num: 5 }
render() {
console.log("更新-03-render渲染")
return (<div>
<h1>生命周期</h1>
<button onClick={() => this.setState({ num: this.state.num + 1 })}>{this.state.num}</button>
</div>);
}
componentDidMount() {
// console.log("挂载-04-componentDidMount")
}
}
export default Life;
5.2 更新
1. static getDerivedStateFromProps props更新触发state更新(要求返回一个新的state) nextProps最新的props ;
2. houldComponentUpdate 组件是否更新,作用优化组件的渲染 返回true更新 false停止更新 常用于组件的优化;
3. render组件重新的渲染;
4. getSnapshotBeforeUpdate 更新前获取快照,返回值是cdu的第三个参数;
5. componentDidUpdate组件已经更新。
import React, { Component } from 'react';
class Life extends Component {
constructor(props) {
super(props);
console.log("挂载-01-constructor")
}
static getDerivedStateFromProps(nextProps, prevState) {
//当props发送变化时候更新state
console.log("更新-01-getDerivedStateFromProps");
return ({})
}
shouldComponentUpdate(nextProps, nextState) {
//组件是否需要更新(组件优化)
console.log("更新-02-shouldComponentUpdate")
return true
}
state = { num: 5 }
getSnapshotBeforeUpdate(prevProps, prevState) {
//组件更新前获取快照,返回的数据是cdu的第三个参数
console.log("更新-04-getSnapshotBeforeUpdate");
return { name: "mumu", age: 18 }
}
componentDidUpdate(prevProps, prevState, snapshot) {
//组件已完成更新
console.log("更新-05-componentDidUpdate", snapshot)
}
render() {
console.log("更新-03-render渲染")
return (<div>
<h1>生命周期</h1>
<button onClick={() => this.setState({ num: this.state.num + 1 })}>{this.state.num}</button>
</div>);
}
}
5.3 卸载
componentWillUnmount 组件将要卸载 作用:移除DOM事件,监听定时器。
六、Hooks
函数组件只有props,react17 更新一个hooks让函数组件拥有类似state与生命周期。
6.1 useState模拟状态
const [num,setNum]=useState(5)
代码解读:模拟num数据默认是5,模拟更新num的方法setNum。
6.2 useEffect使用副作用
注意以下箭头函数中的第二个参数,区别都在这个上面。
1. 模拟生命周期componentDidMount,代码:useEffect(()=>{console.log("componentDidMount")},[]);
2. 模拟生命周期componentDidUpdate,代码:useEffect(()=>{console.log("num更新触发回调函数")},[num]);
3. 模拟生命周期componentWillUnmount,代码:useEffect(()=>{console.log("模拟生命周期componentWillUnmount")},[]);
4. 任意数据的更新,挂载,卸载都会触发,代码:useEffect(()=>{console.log("任意数据更新,挂载,卸载都会触发")})
/src/App.js
import { useEffect, useState } from 'react';
import Test from './components/test'
function App() {
//创建一个state num默认值是5,同时定义设置num的方法
const [num, setNum] = useState(5);
const [count, setCount] = useState(100);
useEffect(() => {
//模拟生命周期的componentDidMount
console.log("回调函数模拟cmd")
}, [])
useEffect(() => {
//模拟生命周期的componentDidUpdate
console.log("回调函数模拟num的更新")
}, [num, count])
return (<div>
<h1>hooks</h1>
<p>函数组件拥有模拟生命周期,模拟state,模拟ref的能力</p>
<button onClick={() => setNum(num + 1)}>{num}</button>
<button onClick={() => setCount(count + 5)}>{count}</button>
{num < 10 ? <Test></Test> : ""}
</div>);
}
export default App;
/src/components/test.js
import { useEffect, useState } from 'react';
function Test() {
const [n, setN] = useState(4);
useEffect(() => {
//返回函数模拟的卸载
return () => console.log("组件将要被卸载")
}, [])
return (<div>
生命周期的卸载
<button onClick={() => setN(n + 2)}>{n}</button>
</div>);
}
export default Test;
掌握以上的基础知识,写一个官网上的井字游戏体验React的奇妙之处是不成问题了,赶紧去去试试吧!