官方文档:https://zh-hans.react.dev/reference/react/useActionState
1.useEffect
useEffect(setup, dependencies?)
1.1 基础使用
//hooks
import { useEffect } from "react";
import "./App.css";
function App(){
useEffect(()=>{
console.log('useEffect loading');
})
return ( <h1>app</h1>)
}
export default App;
执行时机:
1,组件初始化
2,组件更新后执行(在dom更新之后执行)
1.2 传入依赖项时 []
//第一个参数回调函数,组件初始化执行,组件更新后也会执行
useEffect(()=>{
console.log('useEffect loading');
},[])
执行时机:
组件初始化、挂载
1.3 传入依赖项时 [a]
useEffect可以监听到useState的状态变化
(如果依赖项中传入多个值[a,b,c],只有有其中之一变化都会执行useEffect。或的关系)
import { useEffect, useState } from "react";
import "./App.css";
function App() {
const [count, setCount] = useState(0);
//第一个参数回调函数,组件初始化执行,组件更新后也会执行
useEffect(() => {
console.log("useEffect loading");
console.log(count);
// return () => {
// console.log('return 的函数在卸载的时候执行');
// }
}, [count]);
const btn = () => {
setCount(count + 1);
};
return (
<div>
<h1>hooks</h1>
<h1>{count}</h1>
<button onClick={btn}>add</button>
</div>
);
}
export default App;
执行时机:
1,组件初始化、挂载
2,依赖项的状态变化时
1.4 第二个参数不传
第二个参数不传,会将所有定义的state值收集起来,只有有一个值变化了就会执行useEffect
1.5 返回的函数 ☆
执行时机:
1,组件卸载的时候
2,状态发生变化时
useEffect(() => {
console.log("useEffect loading",count);//变化后的数据
return(()=>{//return 中的值是变化之前的数据
console.log('return!!',count);
})
});
应用场景:用于聊天的卸载
用户我跟多个人聊天的场景:
伪代码:
跟用户A
function Bpp(){
useEffect(() => {
//userA
connect(userA)
return(()=>{
console.log('return!!');
})
},[userA]);
}
离开A页面,到用户B
function Bpp(){
useEffect(() => {
//userB
connect(userB)
return(()=>{
//userA
console.log('return!!');
//断开A的连接
disconnect(userA)
})
},[userB]);//A-->B
}
2.useState
const [state, setState] = useState(initialState)
import { useState } from "react";
import "./App.css";
function App() {
const [count, setCount] = useState(0)
const btn=()=>{
setCount(count+1)
}
return (
<div>
<h1>hooks</h1>
<h1>{count}</h1>
<button onClick={btn} >add</button>
</div>
)
}
export default App;
3.useLayoutEffect
useLayoutEffect(setup, dependencies?)
useLayoutEffect 是 useEffect 的一个版本,在浏览器重新绘制屏幕之前触发。
useEffect(() => {
console.log("useEffect loading",count);
});
useLayoutEffect(()=>{
console.log('useLayoutEffect',0);
})
应用场景:
4.性能优化:useMemo
useMemo 是一个 React Hook,它在每次重新渲染的时候能够缓存计算的结果。
useMemo 用于react渲染过程中的性能优化
适用于:父组件要进行更新,子组件的重新render计算量比较大,而且结果可以服用,就可以使用useMemo来缓存数据,提升父组件引起子组件不必要的渲染的性能优化。
注意点:在项目中一定是不得已才使用
1,useMemo本身具有性能消耗,缓存消耗内存,useMemo自身状态的维护也有性能开销
2,useMemo会增加开发成本,代码变得很复杂不好维护
3,react官方在未来会取消useMemo这个钩子
5.性能优化:useCallback
面试题
react的更新是同步还是异步的?为什么?
异步,因为react更新底层的(微任务)异步队列,会将短时间内js对组件的更新合并,1次渲染完成更新。
useEffect的执行时机?
看第一点
useEffect的返回函数执行时机
1,组件卸载的时候
2,状态发生变化时
应用场景:用于聊天的卸载
useEffect和useLayoutEffect区别?
useEffect(异步)是在commit的第一个阶段,js操作dom之前调用,但是在浏览器渲染完成之后调用。
useLayoutEffect(同步),js操作dom之后调用,在浏览器渲染之前。
useMemo作用?
useMemo 用于react渲染过程中的性能优化
适用于:父组件要进行更新,子组件的重新render计算量比较大,而且结果可以服用,就可以使用useMemo来缓存数据,提升父组件引起子组件不必要的渲染的性能优化。
什么时候使用useMemo?
注意点:在项目中一定是不得已才使用
1,useMemo本身具有性能消耗,缓存消耗内存,useMemo自身状态的维护也有性能开销
2,useMemo会增加开发成本,代码变得很复杂不好维护
3,react官方在未来会取消useMemo这个钩子
react渲染规律?
只要父组件进行setState,父组件本身会重新render,所有子组件也会重新render