一、获取接口数据
useEffect会在hook组件渲染(包含第一次和后续每次渲染)的时候重新执行。
useEffect接受两个参数,第一个参数是一个函数,第二参数是一个数组。
若第二个参数为空数组,则表示useEffect只在第一次渲染后执行,后续不再重新执行。此逻辑适合页面第一次渲染加载接口数据的业务场景。
import React, { useState, useEffect } from 'react'
function Example1(){
const [loading, setLoading] = useState(true)
const [data, setData] = useState({})
useEffect(() => {
const fetchData = async () => {
try {
const res = await getInterfaceName(params)
setData(res)
} catch (error) {
throw error
} finally {
setLoading(false)
}
}
fetchData()
}, [])
return (
<div>
{loading ? loading...' : <>{data}</>}
</div>
)
}
export default Example1
二、控制执行时机
依赖项中数据发生变化时候,useEffect会重新执行。实际业务场景中可以根据依赖项实现复杂的业务需求。
import React, { useState, useEffect } from 'react'
function Example2(props){
const { parentState } = props
const [count, setCount] = useState(0)
const [number, setNumber] = useState(0)
useEffect(() => {
const handleNumber = () => {
setNumber(count + 1)
}
handleNumber()
// 点击count事件增加时,因为count发生变化,所以handleNumber函数会重新执行
// 另数组依赖项也可以是父组件传递过来的,当父组件中parentState发生变化,子组件中的handleNumber也会重新执行
}, [parentState, count])
return (
<div>
<p onClick={prevState => setCount(prevState + 1)}>
Count: {count}
</p>
<br />
<p>Number: {number}</p>
</div>
)
}
export default Example2
三、绑定/卸载事件
第一个函数的返回值可以是另一个函数,用于在组件卸载时执行移除监听的事件
import React, { useState, useEffect, useRef } from 'react'
function Example3(){
const [muted, setMuted] = useState(false)
const videoEl = useRef(null)
useEffect(() => {
const videoElement = videoEl.current
videoElement.addEventListener('timeupdate', handleTimeDate, false)
videoElement.addEventListener('loadedmetadata', handleLoadedMetaData, false)
videoElement.addEventListener('durationchange', handleDurationChange, false)
videoElement.addEventListener('play', handlePlay, false)
videoElement.addEventListener('error', handleVideoError, false)
videoElement.addEventListener('waiting', handleVideoWaiting, false)
videoElement.addEventListener('playing', handleVideoPlaying, false)
videoElement.addEventListener('ended', addPlayTimeEvent, false)
return () => {
videoElement.removeEventListener('timeupdate', handleTimeDate)
videoElement.removeEventListener('loadedmetadata', handleLoadedMetaData)
videoElement.removeEventListener('durationchange', handleDurationChange)
videoElement.removeEventListener('play', handlePlay)
videoElement.removeEventListener('error', handleVideoError)
videoElement.removeEventListener('waiting', handleVideoWaiting)
videoElement.removeEventListener('playing', handleVideoPlaying)
videoElement.removeEventListener('ended', addPlayTimeEvent)
}
}, [])
return (
<div>
<video
ref={videoEl}
muted={muted}
src={videoSrc}
autoPlay={true}
>
</video>
</div>
)
}
export default Example3