最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React useCallback使用教程

 更新時(shí)間:2023年01月05日 10:53:29   作者:折桂懷橘  
useCallback是react中比較重要的一個(gè)hook,useCallback 用來(lái)返回一個(gè)函數(shù),在父子組件傳參或者通用函數(shù)封裝中,起到舉足輕重的作用

開(kāi)始之前請(qǐng)注意這句話:任何優(yōu)化都會(huì)增加復(fù)雜性,任何過(guò)早添加的優(yōu)化都會(huì)帶來(lái)風(fēng)險(xiǎn),因?yàn)閮?yōu)化后的代碼可能會(huì)多次更改

useEffect

相關(guān)作用:監(jiān)聽(tīng) & 初始化

//最簡(jiǎn)單用法
   useEffect(() => {
     //只有方法體,相當(dāng)于componentDidMount和componentDidUpdate中的代碼
    document.title = count;
  })
  //加返回值用法
  useEffect(() => {
    //添加監(jiān)聽(tīng)事件,相當(dāng)于componentDidMount和componentDidUpdate中的代碼
    window.addEventListener('resize', onChange, false);
    //返回的函數(shù)用于解綁事件,相當(dāng)于componentWillUnmount中的代碼
    return () => {
      window.removeEventListener('resize', onChange, false)
    }
  })
  //加空數(shù)組參數(shù)用法
  useEffect(() => {
    // 相當(dāng)于 componentDidMount
    window.addEventListener('resize', onChange, false)
    return () => {
      // 相當(dāng)于 componentWillUnmount
      window.removeEventListener('resize', onChange, false)
    }
  }, []);
  //加監(jiān)聽(tīng)值用法
  useEffect(() => {
   //只有當(dāng)count的值發(fā)生變化,此函數(shù)才會(huì)執(zhí)行
    console.log(`count change: count is ${count}`)
  }, [ count ]);

useCallback

先看一個(gè)最簡(jiǎn)單的例子:

// 用于記錄 getData 調(diào)用次數(shù)
let count = 0;
function App() {
  const [val, setVal] = useState("");
  function getData() {
    setTimeout(()=>{
      setVal('new data '+count);
      count++;
    }, 500)
  }
  useEffect(()=>{
    getData();
  }, []);
  return (
    <div>{val}</div>
  );}

getData模擬發(fā)起網(wǎng)絡(luò)請(qǐng)求。在這種場(chǎng)景下,沒(méi)有useCallback什么事,組件本身是高內(nèi)聚的。

如果涉及到組件通訊,情況就不一樣了:

// 用于記錄 getData 調(diào)用次數(shù)
let count = 0;
function App() {
  const [val, setVal] = useState("");
  function getData() {
    setTimeout(() => {
      setVal("new data " + count);
      count++;
    }, 500);
  }
  return <Child val={val} getData={getData} />;}function Child({val, getData}) {
  useEffect(() => {
    getData();
  }, [getData]);
  return <div>{val}</div>;}

就這么輕輕松松,一個(gè)死循環(huán)就誕生了…

先來(lái)分析下這段代碼的用意,Child組件是一個(gè)純展示型組件,其業(yè)務(wù)邏輯都是通過(guò)外部傳進(jìn)來(lái)的,這種場(chǎng)景在實(shí)際開(kāi)發(fā)中很常見(jiàn)。

再分析下代碼的執(zhí)行過(guò)程:

  • App渲染Child,將val和getData傳進(jìn)去
  • Child使用useEffect獲取數(shù)據(jù)。因?yàn)閷?duì)getData有依賴,于是將其加入依賴列表
  • getData執(zhí)行時(shí),調(diào)用setVal,導(dǎo)致App重新渲染
  • App重新渲染時(shí)生成新的getData方法,傳給Child
  • Child發(fā)現(xiàn)getData的引用變了,又會(huì)執(zhí)行g(shù)etData
  • 3 -> 5 是一個(gè)死循環(huán)

如果明確getData只會(huì)執(zhí)行一次,最簡(jiǎn)單的方式當(dāng)然是將其從依賴列表中刪除。但如果裝了 hook 的lint 插件,會(huì)提示:React Hook useEffect has a missing dependency

useEffect(() => {
  getData();}, []);

實(shí)際情況很可能是當(dāng)getData改變的時(shí)候,是需要重新獲取數(shù)據(jù)的。這時(shí)就需要通過(guò)useCallback來(lái)將引用固定?。?/p>

const getData = useCallback(() => {
  setTimeout(() => {
    setVal("new data " + count);
    count++;
  }, 500);}, []);

上面例子中g(shù)etData的引用永遠(yuǎn)不會(huì)變,因?yàn)樗囊蕾嚵斜硎强铡?梢愿鶕?jù)實(shí)際情況將依賴加進(jìn)去,就能確保依賴不變的情況下,函數(shù)的引用保持不變。

還有一個(gè)要注意的是

在開(kāi)始監(jiān)聽(tīng)一個(gè)鼠標(biāo)的移動(dòng)的時(shí)候,想要?jiǎng)h除這個(gè)監(jiān)聽(tīng)不生效,由于是, 加入useState導(dǎo)致組件再次渲染 handleMouse 函數(shù)在次渲染, handleMouse 作為組件內(nèi)的方法, 會(huì)跟著一同再次渲染, 并且在內(nèi)存里, 再次渲染出的 clickFunc !== 前clickFunc.

所以removeEventListener無(wú)法解除綁定, 再次addEventListener則會(huì)綁定一個(gè)新方法.

document.addEventListener('mousemove',handleMouse,true)

解決方案 : useCallback 緩存改方法 這時(shí)候的 document.removeEventListener(‘mousemove’,handleMouse,true) 中的handleMouse 和添加中的方法就是一個(gè)了,就能刪除了。

onst handleMouse= useCallback(() => {
//xxxx
    console.log("clicking");
  }, []);

到此這篇關(guān)于React useCallback使用教程的文章就介紹到這了,更多相關(guān)React useCallback內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

河西区| 祁连县| 辽宁省| 浑源县| 宜春市| 古蔺县| 玉门市| 鹿泉市| 余江县| 罗定市| 财经| 龙口市| 博罗县| 板桥市| 东光县| 栖霞市| 瓦房店市| 兴国县| 山东省| 东兴市| 东乡族自治县| 青岛市| 南安市| 锡林浩特市| 汤原县| 滦平县| 越西县| 胶州市| 家居| 阳朔县| 剑阁县| 淮安市| 永和县| 万源市| 大丰市| 阿拉尔市| 同心县| 沂源县| 水富县| 贵阳市| 集贤县|