文章目录
前言
一、React Hooks是什么?
React Hooks是目前数据React 最火的新特性,改变了原始React继承类组件的方式,改为函数式组件,并且采用预函数的形式管理state,极大提高组件复用效率。
二、前期项目准备
需要注意,初始化create-react-app项目时,项目文件夹名字不能有大写
create-react-app react_hooks_demo //创建项目
cd react_hooks_demo //cd 到项目目录
yarn start //启动项目
三、React Hooks 编写形式与类继承形式对比
原始类继承式组件写法:创建
OriginExample.js
//原始类继承式组件写法
import React, { Component } from 'react';
export default class OriginExample extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
//射击事件
ShootClick = () => {
this.setState({
count:this.state.count+1
})
}
render() {
return (
<div>
<h1>原始类继承component写法</h1>
<p>你已经射击了{this.state.count}次!</p>
<button onClick={this.ShootClick}>射击</button>
</div>
);
}
}
React Hooks函数式组件写法:创建HooksExample.js
import React, { useState } from 'react';
export default function HooksExample() {
const [count, setCount] = useState(0); //count 初始值为0
return (
<div>
<h1>React Hooks 写法</h1>
<p>你已经射击了{count}次!</p>
<button onClick={()=>{setCount(count+1)}}>射击</button>
</div>
)
}
四、useState 的介绍和多状态声明
1.useState 的介绍
useState
是React自带的一个hook函数,作用是声明,读取,修改变量(下面是useState的源码)
function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
/**
* 返回一个有状态值和一个更新它的函数。
*/
useState
这个函数接受一个initialState
初始值参数,同时返回一个状态值
以及更新此状态值的函数
const [count, setCount] = useState(0); //count 初始值为0
所以上述初始化useState
使用了ES6中数组解构
的语法,将状态值
以及更新函数
解构
1.多状态声明的注意事项
React Hook 不能出现在条件判断语句中,需要保持完全一样的渲染顺序
import React, { useState } from 'react';
export default function HooksExample() {
const [count, setCount] = useState(0); //count 射击次数初始值为0
const [bulletCount, setBulletCount] = useState(20); //count 子弹初始值为100
const ActionClick = () => {
setCount(count + 1);
setBulletCount(bulletCount - 1)
}
return (
<div>
<h1>React Hooks 写法</h1>
<p>你已经射击了{count}次!</p>
{
bulletCount === 0 ? (
<p style={{ color: "red" }} >你已经弹尽粮绝了!</p>
) : (
<p style={{ color: "greenyellow" }} >还有{bulletCount}发子弹!</p>
)
}
<button onClick={ bulletCount>0?ActionClick:alert("你没子弹了!")}>射击</button>
</div>
)
}
按顺序声明多个状态就可以,如果在React Hook 出现在条件语句中,程序就会报错
五、useEffect
代替常用生命周期函数
1.用Class
继承方式使用生命周期函数
在
OriginExample.js
中加入生命周期函数
componentDidMount(){
//组件挂载完成
console.log(`组件挂载完成=>你射击了${this.state.count}次!`)
}
componentDidUpdate(){
//组件更新完成
console.log(`组件更新完成=>你射击了${this.state.count}次!`)
}
效果如下:
2.useEffect
函数代替class中生命周期函数
在
HooksExample.js
中加入useEffect
代码
import React, { useState ,useEffect} from 'react';
export default function HooksExample() {
const [count, setCount] = useState(0); //count 射击次数初始值为0
const [bulletCount, setBulletCount] = useState(20); //count 子弹初始值为100
const ActionClick = () => {
setCount(count + 1);
setBulletCount(bulletCount - 1)
}
//使用useEffect函数代替生命周期函数
useEffect(() => {
console.log(`useEffect=>你射击了${count}次!`)
})
return (
<div>
<h1>React Hooks 写法</h1>
<p>你已经射击了{count}次!</p>
{
bulletCount === 0 ? (
<p style={{ color: "red" }} >你已经弹尽粮绝了!</p>
) : (
<p style={{ color: "greenyellow" }} >还有{bulletCount}发子弹!</p>
)
}
<button onClick={ bulletCount>0?ActionClick:alert("你没子弹了!")}>射击</button>
</div>
)
}
结果如下:
六、使用useEffect
实现componentWillUnmount
组件卸载函数
代替componentWillUnmount
函数功能
学习这个功能需要使用
路由
来切换页面触发componentWillUnmount
组件卸载函数,所以要在项目中添加react-router-dom
库
npm
npm install react-router-dom
yarn
yarn add react-router-dom
下载完
react-router-dom
之后在程序引入
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
完整代码:
import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
//css
const routeCssObj = {
display: "flex",
justifyContent: "space-around",
listStyleType: "none",
margin: "10% auto" ,
}
const redBgc = { backgroundColor: "#F34725" ,color:"white"}
const blueBgc = { backgroundColor: "#25D0F3" ,color:"white"}
//声明两个组件
function Red() {
//Red组件内生命周期函数
useEffect(()=>{
console.log("我们一起进入了Red组件!!!!!")
return ()=>{
console.log("我们离开了Red组件------------------")
}
})
return <h1 style={redBgc}>Red组件</h1>
}
function Blue() {
//Blue组件内生命周期函数
useEffect(()=>{
console.log("我们一起进入了Blue组件!!!!!")
return ()=>{
console.log("我们离开了Blue组件------------------")
}
})
return <h1 style={blueBgc}>Blue组件</h1>
}
export default function HooksExample() {
//声明两个组件当作路由组件
const [routeObj] = useState([
{
path: "/red",
name: "Red组件",
component: Red
},
{
path: "/blue",
name: "Blue组件",
component: Blue
}
])
return (
<div>
{/* 路由配置,需要学习react路由相关的前置知识 */}
<Router>
<ul style={routeCssObj}>
{
routeObj.map((item, index) => {
return <li key={index}><Link to={item.path}>{item.name}</Link></li>
})
}
</ul>
{
routeObj.map((item, index) => {
return <Route key={index} path={item.path} component={item.component}></Route>
})
}
</Router>
</div>
)
}
实现效果:
2.useEffect
中第二个参数(两种情况)
- 第二个参数为空数组 :
[]
当我们第二个参数传入[]
时,表示当组件被销毁时才进行解绑 - 第二个参数为
状态变量
:比如之前声明的count
这个时候只要count状态发生变化,就会执行解绑函数
总结
学如逆水行舟,不进则退