目录
我们知道,函数式组件是没有状态绑定,生命周期等特性的,为此,衍生出了hooks钩子函数,来弥补函数式组件的不足。
一、useState():状态钩子
这里,将用函数式组件,实现如下的user的获取渲染。
1、导入useState关键字,利用useState设置初始值,并且解构出变量名和操控变量的方法函数。
2、渲染页面,绑定状态。
3、利用绑定的方法,修改state。
如此,便可以实现state的改变。完整代码如下。
import React,{ useState,} from "react"
export default function Countfun() {
const [name, setName] = useState("zs")
const [age, setAge] = useState(18)
const changeAge = (type) => {
//根据点击加减号的不同,设置年龄
let newAge = type === 1 ? age + 1 : age - 1
setAge(newAge)
}
const getNewName = (e) => {
//失焦获取input的值,将其赋值给姓名一栏
const newName = e.target.value
setName(newName)
//清空input
e.target.value = ""
}
return (
<>
<h4>个人信息</h4>
<p>姓名:
<span>{name}</span>
<input placeholder="请输入新名字" onBlur={getNewName} />
</p>
<p>年龄:
<span>{age}</span>
<i onClick={()=>changeAge(1)}> 加一 </i>
<i onClick={()=>changeAge(2)}> 减一 </i>
</p>
</>
)
}
二、useEffect():作用钩子(生命周期)
1、依旧是导入useEffect 。
useEffect有两个参数,第一个是执行函(执行函数中如果return出函数,则那个函数是销毁时执行),第二个是数组,放入依赖项(对某一state值的监听,只要这个数组的依赖项发生变化,useEffect()
就会执行,如果为空,则是组件被销毁时渲染)。
下面会详细的介绍他们的两个参数。
2、写一个路由,用来切换组件的渲染,从而发生组件的生成和销毁。页面和代码如下。
import React, { Component } from 'react'
import Count from './components/count'
import Countfun from './components/fun-count'
import {BrowserRouter as Router, Routes, Route, NavLink} from 'react-router-dom'
import "./App.css"
export default class App extends Component {
render() {
return (
<Router>
<div>
<div className='head'>
<h4><NavLink to="/class/component" activeclassname = "actice">类组件</NavLink></h4>
<h4><NavLink to="/func/component" activeclassname = "active">函数式组件</NavLink></h4>
</div>
<div className='body'>
<Routes>
<Route path='/class/component' element={<Count />}></Route>
<Route path='/func/component' element={<Countfun />}></Route>
</Routes>
</div>
</div>
</Router>
)
}
}
3、参数 一。相当于componentDidMount,在组件创建时异步加载执行,里面可以放入请求。
如果希望组件在被销毁时,执行componentWillMount函数,那需要在该参数中return出一个函数,里面可以写入销毁操作。(此时需要写上第二个参数,且为空,否则该return的函数,将会在加载时也执行)
切换路由,可以看到,组件销毁和加载都已经执行
4、参数二,数组中放入依赖项,也就是状态state,如果状态发生变更,则会渲染该函数。
这里依赖name和age,当这两个变更时,函数将被执行。
可以看到,点击加一,age加一时,该函数执行了。
三、useContext():共享状态钩子,用于祖孙传值
和类组件使用Provider和Consumer相似,这里不再过多赘述。
祖宗组件:作为提供者,提供值
孩子组件:作为消费者,消费值
四、useRef
和useState 一样,导入之后,创建一个ref,将其绑定给对应的dom元素。
然后点击年龄18,即可获取到dom元素
五、useReducer
这里将用useContext和useReducer简单的实现一下Redux。
实现样式:自增加n,自减减n,并在页面渲染,打印台监听。
1、先创建store仓库,书写reducer函数和action函数
a、reducer函数,用来分发action行为
export default function reducer(state,action) {
switch (action.type) {
case "add":
return {...state,count:state.count + action.num}
case "sub":
return {...state,count:state.count - action.num}
default:
break;
}
}
b、action函数,实现改变状态的行为,并接受加减的值
export const action1 = (num) => ({type:"add",num: num})
export const action2 = (num) => ({type:"sub",num: num})
2、在要挂载的页面导入reducer和actions,并且创建数据仓库
3、对应的的函数祖宗函数组件中,利用useReducer导入reducer函数和store仓库(图一)
同时,将state状态和dispatch分发函数交给孙子组件。(图二)
4、对应的孙子组件,渲染数据,修改数据
5、最终实现 ,点击对应的按钮,实现页面渲染和打印台监听