日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
重點(diǎn)來了,UseEffect如何讓使用者在函數(shù)組件中執(zhí)行副作用操作

作者 |這波能反殺丶

來源 |這波能反殺(ID:keepKilling)

當(dāng)了二十多天廢物,今天開始更新,讓大家久等了?;送﹂L的時(shí)間優(yōu)化文章 UI 細(xì)節(jié),進(jìn)一步提高閱讀體驗(yàn),大家多多感受一下.

useEffect 是一個(gè)難以掌握的知識點(diǎn)。許多人對它半知半解,因此他們覺得函數(shù)式組件不受控制。

除了本身難以理解之外,React 還提供了一個(gè)類似的 hook:useLayoutEffect 來增加學(xué)習(xí)難度,對于新手來說,這可要了老命了。

許多朋友試圖利用 class 語法中的生命周期來類比理解 useEffect,因?yàn)楣俜轿臋n就是這么引導(dǎo)的,那么他們多半會陷入一些誤區(qū),因此,學(xué)習(xí)之前,大家需要明確的是,生命周期函數(shù)與 useEffect 是不同的。

要充分理解并使用該方法,你需要對閉包、同步、異步、事件循環(huán)等基礎(chǔ)概念有清晰認(rèn)知。

一、概念

useEffect 可以讓使用者在函數(shù)組件中執(zhí)行副作用操作。

那什么是副作用操作呢?

在 React 中,由 state 的變化導(dǎo)致 UI 發(fā)生變化的過程是正常操作,其他操作行為:例如數(shù)據(jù)請求、直接手動(dòng)修改 DOM 節(jié)點(diǎn)、直接操作頁面「修改頁面標(biāo)題等」、記錄日志等都是副作用操作。

副作用操作是相對于操作 state 而言的。

每一次因?yàn)?state 的改變,都有一次對應(yīng)副作用函數(shù)的執(zhí)行時(shí)機(jī)。如果 state 多次改變,那么就有多次對應(yīng)副作用的執(zhí)行時(shí)機(jī)。

例如:我希望記錄點(diǎn)擊的次數(shù)。

該次數(shù)不僅要在頁面上顯示,也要在頁面標(biāo)題中顯示。

我們就可以給出如下代碼來實(shí)現(xiàn)需求。

import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (

You clicked {count} times




);
}

在該例子中,修改頁面標(biāo)題的行為是副作用行為,因此我們可以直接使用 useEffect 來定義它。useEffect 的第一個(gè)參數(shù)為一個(gè)回調(diào)函數(shù),該回調(diào)函數(shù)就是我們上面說的副作用函數(shù)「effect」,我們想要執(zhí)行的副作用邏輯都寫在該函數(shù)中。

二、語法

// 中括號表示參數(shù)可選
useEffect(effct[, deps])

useEffect 是 React 提供的 Hook,它能夠幫助我們定義 effect 函數(shù)。

第一個(gè)參數(shù)就是副作用函數(shù) effect。

第二個(gè)參數(shù)表示依賴項(xiàng),是一個(gè)可選參數(shù)。當(dāng)不傳入該參數(shù)時(shí),每次 UI 渲染 effect 函數(shù)都會執(zhí)行。

但是大多數(shù)時(shí)候我們并不想任何 state 的變化都一定要執(zhí)行 effect 函數(shù),這個(gè)時(shí)候我們可以傳入依賴項(xiàng)數(shù)組。使用時(shí)請確保依賴項(xiàng)數(shù)組中為 state/props 的值,表示 effect 只會響應(yīng)依賴項(xiàng)中狀態(tài)的變化。

如果你在 useEffect 中傳入與 state 無關(guān)的數(shù)據(jù),effect 不會響應(yīng)它們。

只有當(dāng)依賴項(xiàng)中是 state 發(fā)生變化時(shí),effect 才會與之對應(yīng)的執(zhí)行。

不同的 state 數(shù)據(jù)變化通常對應(yīng)不同的副作用操作。因此我們可以在函數(shù)組件中,定義多個(gè) effect。

function Demo() {
const [count, setCount] = useState(0)
const [show, setShow] = useState(false)
useEffect(() => {
// do something
}, [count])
useEffect(() => {
// do other something
}, [show])
...
}

除此之外,我們還可以傳入空數(shù)組作為依賴項(xiàng),用于表示依賴項(xiàng)不會發(fā)生變化。因此,空數(shù)組對應(yīng)的 effect,就只會在初始化時(shí)執(zhí)行一次,以后就再也不會執(zhí)行了。

我們通常利用這個(gè)特性完成一些初始化工作,例如請求頁面數(shù)據(jù)。

const [list, setList] = useState(0);
// DOM渲染完成之后 effect 函數(shù)執(zhí)行
useEffect(() => {
recordListApi().then(res => {
setList(res.data);
})
}, []);

三、清除副作用

有的時(shí)候,副作用函數(shù) effect 執(zhí)行會留下一些痕跡,因此 useEffect 提供了一種清除副作用的方式。

effect 與 clear effect 是一一對應(yīng)的緊密關(guān)系。因此,我們可以定義一個(gè)回調(diào)函數(shù)由 effect 執(zhí)行時(shí)返回,該函數(shù)就是 clear effect 函數(shù)。

useEffect(() => {
// dosomething
// 定義 clear effect 函數(shù)
return () => {
// clear something
}
}, [])

這里一定要注意該函數(shù)與 class 組件中的 componentWillUnmount 的區(qū)別,官方文檔中的案例存在一定的誤導(dǎo)性。如果 deps 傳入空數(shù)據(jù),則兩者是類似的,否則他們完全不一樣,effect 與 clear effect 都有可能執(zhí)行多次。

clear effect 在下次 effect 執(zhí)行之前執(zhí)行,也會在組件銷毀之前執(zhí)行一次。

我們可以借助該特性實(shí)現(xiàn)一個(gè)防抖的案例。

例如我們要實(shí)現(xiàn)一個(gè)搜索框的功能。文字輸入過程中會自動(dòng)發(fā)起搜索請求。為了防止請求發(fā)送過于頻繁,在高頻輸入時(shí),不發(fā)送接口請求,如果超過了 500ms 下一次輸入事件還沒有發(fā)生,那么就自動(dòng)請求一次。

實(shí)現(xiàn)代碼如下:

import { useEffect, useState } from 'react'
export default function EffectDemo() {
const [text, setText] = useState('')
useEffect(() => {
let timer = setTimeout(() => {
console.log('發(fā)送搜索請求')
}, 500)
return () => {
console.log('清除定時(shí)器')
clearTimeout(timer)
}
}, [text])
return (

setText(e.target.value)} />

)
}

我們在 effect 中定義了定時(shí)器,作為延遲操作:500ms 后執(zhí)行請求邏輯。如果下一次 text 快速發(fā)生變化,clear effect 執(zhí)行會清除掉上一次定義的定時(shí)器任務(wù),那么請求邏輯就不會執(zhí)行。

只有下一次 text 的改變超過了 500ms 時(shí),定時(shí)器任務(wù)才會如期執(zhí)行。

執(zhí)行順序?yàn)椋?/p>

四、案例

在學(xué)習(xí)和理解 effect 的含義時(shí),我們知道 state 的變化引發(fā) UI 重新渲染,UI 渲染完成之后會執(zhí)行 effect。

然而在真實(shí)實(shí)踐時(shí),我們往往是知道自己要執(zhí)行的副作用邏輯是什么,難的是需要我們自己去設(shè)計(jì)合理的 state。不合理的設(shè)計(jì)會讓程序變得復(fù)雜。

現(xiàn)在我們要來實(shí)現(xiàn)下面的動(dòng)畫效果:

  1. 點(diǎn)擊紅色畫布,白色方塊執(zhí)行第一段動(dòng)畫,并顯示執(zhí)行日志。
  2. 執(zhí)行完后緊接著執(zhí)行第二段動(dòng)畫回到圓點(diǎn),并顯示執(zhí)行日志。
  3. 在白色方塊執(zhí)行動(dòng)畫的過程中點(diǎn)擊事件無效:點(diǎn)擊不影響動(dòng)畫的執(zhí)行,結(jié)束之后重新生效。

這個(gè)效果的實(shí)現(xiàn),最重要的是對于幾個(gè)狀態(tài)的設(shè)計(jì)。

首先,我們需要用一個(gè)狀態(tài)來表示第一段動(dòng)畫的執(zhí)行與否 anime01。

其次,我們需要用一個(gè)狀態(tài)來表示第二段動(dòng)畫的執(zhí)行與否 anime02。

最后,我們也可以使用一個(gè)額外的狀態(tài)來判斷整個(gè)過程是否已經(jīng)執(zhí)行完畢 stoped。

重點(diǎn)思考該狀態(tài)的特性,與存在的必要性。

在實(shí)現(xiàn)該邏輯中,我們只需要知道每一個(gè)運(yùn)動(dòng)的結(jié)束時(shí)間點(diǎn),并修改對應(yīng)的狀態(tài)即可。

例如:第一段動(dòng)畫執(zhí)行結(jié)束,修改 anime02 為true。

完整代碼如下:

import { useState, useRef, useEffect } from 'react';
// @ts-ignore
import anime from 'animejs';
import './style.scss';
export default function AnimateDemo() {
const [anime01, setAnime01] = useState(false);
const [anime02, setAnime02] = useState(false);
const element = useRef(null);
// 是否已經(jīng)停下來了
const stoped = useRef(true)
useEffect(() => {
anime01 && animate01();
anime02 && animate02();
}, [anime01, anime02]);
function animate01() {
anime({
targets: element.current,
translateX: 400,
backgroundColor: '#FF8F42',
borderRadius: ['0%', '50%'],
complete: () => {
setAnime01(false)
setAnime02(true)
}
})
}
function animate02() {
anime({
targets: element.current,
translateX: 0,
backgroundColor: '#FFF',
borderRadius: ['50%', '0%'],
easing: 'easeInOutQuad',
complete: () => {
setAnime02(false);
stoped.current = true
}
})
}
function clickHandler() {
if (stoped.current) {
stoped.current = false
setAnime01(true);
}
}
return (


{anime01 &&
第一段動(dòng)畫執(zhí)行中
}
{anime02 &&
第二段動(dòng)畫執(zhí)行中
}

)
}

這個(gè)案例值得我們進(jìn)一步思考,一方面是數(shù)據(jù)為什么需要使用 state 或者 ref. 另一方面是關(guān)于 effect 是否還有另外一個(gè)角度的思考。


標(biāo)題名稱:重點(diǎn)來了,UseEffect如何讓使用者在函數(shù)組件中執(zhí)行副作用操作
文章分享:http://m.5511xx.com/article/dghhghi.html