hooks的出现意义
- hooks之间的状态是独立的,有自己的独立上下文,不会出现混淆状态的情况
- 让函数组件有了状态管理
- 解决了组件数不直观、类组件难维护、逻辑不易复用的问题
- 由于函数每次渲染都会执行,所以react中多了一个状态控制,传入第二个参数。这样就可以避免函数重复执行的副作用
为什么学习hooks
- 高效开发
- 提高组件的复用性
- 提高逻辑的复用性
- 提升性能
- 实现复杂的逻辑性能
应用场景
- 利用hooks取代生命周期函数
- 让函数组件上加上状态
- 组件辅助函数
- 处理发送请求
- 存取数据
- 性能优化
创建项目
npm install create-react-app -g 全局安装脚手架
create-react-app -V 查看脚手架版本
create-react-app app 创建项目
接下来我们就可以拥抱react函数式编程了!
1、useState的使用
//使用useState来创建状态
/**
* 1.引入
* 2.接收一个参数作为初始值
* 3.返回一个数组,第一个值为状态,第二个为改变状态的函数
* @returns {*}
* @constructor
*/
import React, { useState} from 'react'
function StateFunction() {
const [num, setNum] = useState(1); //写法
return (
<div>
//点击修改值
<div onClick={()=>setNum(num=>num+1)}>这是一个函数式组件{num}</div>
</div>)
}
export default StateFunction
2.useEffect、useLayoutEffect的使用
**useEffect 与 useLayoutEffect相似的用法**
1.接收一个函数作为初始值
2.接收第二个参数依赖列表,只有依赖更新时,才会执行函数
3.返回一个函数,先执行返回函数,再执行参数函数
import React, {
useState,
useEffect,
useLayoutEffect,
} from 'react'
function StateFunction() {
const [num, setNum] = useState(1);
useEffect(()=>{
console.log('useEffect')
},[])
useLayoutEffect(()=>{
console.log('useLayoutEffect')
},[])
return (
<div>
<div onClick={()=>setNum(num=>num+1)}>这是一个函数式组件{num}</div>
</div>)
}
export default StateFunction
**useEffect 与 useLayoutEffect不同的用法**
1.useEffect执行时机在render之后
2.useLayoutEffect在dom更新之后
3.useMemo的使用
useMemo 让组件中的函数跟随状态更新
1.接收一个函数作为参数
2.第二个参数作为依赖列表
3.返回的是一个值
import React, {
useState,
useMemo,
} from 'react'
function StateFunction() {
const [num, setNum] = useState(1);
const [age, setAge] = useState(18);
//不使用useMemo
const getDoubleNum =(()=>{
console.log('执行双倍改变')
return num*2
})
//使用useMemo,不跟随其他状态改变执行
const getDoubleNum1 =useMemo(()=>{
console.log('执行双倍改变');
return num*2
},[num])
return (
<div>
<div onClick={()=>setNum(num=>num+1)}>这是一个函数式组件,获取双倍数{getDoubleNum1} 年龄{age}</div> //跟随num变化执行
<div onClick={()=>setAge(key=>key+1)}>这是一个函数式组件,获取双倍数{getDoubleNum1} 年龄{age}</div> //不跟随age变化执行
</div>)
}
export default StateFunction
4.useCallback的使用
useCallback与useMemo使用方法相同,useCallback返回的是一个函数
import React, {
useState,
useCallback,
} from 'react'
function StateFunction() {
const [num, setNum] = useState(1);
const getDoubleNum = useCallback(()=>{
return num*2
},[num])
return (
<div>
<div onClick={()=>setNum(num=>num+1)}>这是一个函数式组件{num}</div>
<Child callback={getDoubleNum()}></Child>
</div>)
}
function Child (props){
console.log(props)
return <div>child {props.callback}</div>
}
export default StateFunction
5.useRef的使用
1.长久保存数据
2.保存一个值在整个生命周期中维持不变
3.重新赋值ref.current不会重新渲染
function StateFunction() {
const [num, setNum] = useState(1);
const ref = useRef()
useEffect(() => {
ref.current = setInterval(() => {
setNum(num => num + 1)
}, 1000)
return (() => {
// console.log('销毁')
})
},[])
useEffect(() => {
if (num >= 10) {
clearInterval(ref.current)
}
return (() => {
// console.log('销毁11')
})
}, [num])
return (
<div>
{/*<div onClick={() => setNum(num => num + 1)}>这是一个函数式组件{num}</div>*/}
<div>这是一个函数式组件{num}</div>
</div>)
}
export default StateFunction
6.useContext与createContext的使用
1.首先需要引入useContext、createContext两个内容
2.通过CreateContext创建一个Context句柄
3.Context.Provider来确定数据共享的范围
4.通过value来分发内容
5.在子组件中,通过useContext(Context句柄)来获取数据
import React, {
useState,
useEffect,
useContext,
createContext,
} from 'react'
const Context = createContext(null)
function StateFunction() {
const [num, setNum] = useState(1);
return <div>
这是一个函数式组件{num}
<Context.Provider value={num}>
<Item1></Item1>
<Item2></Item2>
</Context.Provider>
</div>
}
function Item1() {
const num = useContext(Context)
return <div>子组件1{num}</div>
}
function Item2() {
const num = useContext(Context)
return <div>子组件2{num+1}</div>
}
export default StateFunction
7.useReducer
1.需要创建数据仓库和管理者reducer
2.通过useReducer(reducer,store)来获取state和dispatch
import React, {
useState,
useReducer,
} from 'react'
const store ={
num:10
}
const reducer=((state,action)=>{
switch (action.type) {
case 'hangchangeNum':
return {
...state,
num:action.num
}
default :
return{
...state
}
}
})
function StateFunction() {
const [num, setNum] = useState(1);
const [state,dispatch] = useReducer(reducer,store)
return <div onClick={()=>{
dispatch({
type:'hangchangeNum',
num:100
})
}
}>
这是一个函数式组件 {state.num}
</div>
}
export default StateFunction
交流
1、QQ群:可添加qq群共同进阶学习: 进军全栈工程师疑难解 群号: 856402057
2、公众号:公众号「进军全栈攻城狮」
对前端技术保持学习爱好者欢迎关注公众号共同学习。在进阶的路上,共勉!