AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

蛻變之始,useEffect 最后一種用法

來源: 責編: 時間:2024-01-02 09:28:32 227觀看
導讀在 React 官方文檔中,對于 useEffect 有這樣一句描述:Effects are an escape hatch from the React paradigm。這句話怎么理解呢?我們要結合前面的哲學部分進行思考。React 開發指導思想是數據驅動 UI,因此在 React 程序

Fzp28資訊網——每日最新資訊28at.com

在 React 官方文檔中,對于 useEffect 有這樣一句描述:Effects are an escape hatch from the React paradigm。Fzp28資訊網——每日最新資訊28at.com

這句話怎么理解呢?我們要結合前面的哲學部分進行思考。React 開發指導思想是數據驅動 UI,因此在 React 程序中,我們總是會思考如何設計與 UI 保持一致的數據,把解決問題的重心放在數據邏輯上。Fzp28資訊網——每日最新資訊28at.com

但是這樣的思路并不能應對所有場景。在一些特殊的場景里,我們需要跳出數據驅動 UI 的解題思路,例如為了避免出現性能瓶頸,在高頻率的事件監聽中,我們會選擇直接使用原生 DOM 節點來解決問題。Fzp28資訊網——每日最新資訊28at.com

意思就是說,如果你想要跳出 React 的環境使用其他的方式開發,可以把 effect 作為一個對外接口。Fzp28資訊網——每日最新資訊28at.com

官方文檔也對此有進一步的解釋:Fzp28資訊網——每日最新資訊28at.com

They let you “step outside” of React and synchronize your components with some external system like a non-React widget, network, or the browser DOMFzp28資訊網——每日最新資訊28at.com

這樣的 escape hatch 給 React 帶來了極大的靈活性。在一個復雜的項目中,我們可以使用 React 解決一部分邏輯,然后使用別的更合適的方案解決另外的問題,這樣的靈活性提高了 React 項目的上限。這也是 React 能參與到類似于 Figma 這樣龐大、復雜、對性能要求極高的項目中去的原因。Fzp28資訊網——每日最新資訊28at.com

Fzp28資訊網——每日最新資訊28at.com

FigmaFzp28資訊網——每日最新資訊28at.com

一、如何運用

useEffect 第二個參數為一個數組,當我們傳入的參數為一個空數組時,表示 effect 僅會在組件首次渲染完成時執行。Fzp28資訊網——每日最新資訊28at.com

useEffect(effect, [])

只要我們確保當前組件在程序運行過程中相對穩定,不會隨時被刪除,那么我們就可以在 effect 中獲取原生 DOM 節點,并添加綁定事件,回歸到原生 DOM 開發思路中去,你甚至可以在這里繼續使用 jQuery。Fzp28資訊網——每日最新資訊28at.com

我們也可以在這里放心使用百度地圖 javaScript sdk,從而完整的在 react 項目中嵌入百度地圖。Fzp28資訊網——每日最新資訊28at.com

function App() {  // ...  useEffect(() => {    var mp = new BMapGL.Map('map');     mp.centerAndZoom(new BMapGL.Point(121.491, 31.233), 11);   }, [])  // ...}

或者與 echarts 結合使用。Fzp28資訊網——每日最新資訊28at.com

function App() {  const main = useRef(null)  useEffect(() => {    var myChart = echarts.init(main.current);    // 指定圖表的配置項和數據    var option = {      title: {        text: 'ECharts 入門示例'      },      tooltip: {},      legend: {        data: ['銷量']      },      xAxis: {        data: ['襯衫', '羊毛衫', '雪紡衫', '褲子', '高跟鞋', '襪子']      },      yAxis: {},      series: [        {          name: '銷量',          type: 'bar',          data: [5, 20, 36, 10, 10, 20]        }      ]    };    // 使用剛指定的配置項和數據顯示圖表。    myChart.setOption(option);  }, [])  return (    <div id="main" ref={main}></div>  )}

其他的例子還有很多,我們這里使用一個案例來進一步感受 React 與原生 DOM 開發結合的方式。Fzp28資訊網——每日最新資訊28at.com

二、需求

在長頁面滾動的過程中,我們常常會在頁面的頂部或者旁邊,放一個標識組件來告訴用戶頁面已經滾動到什么位置了。Fzp28資訊網——每日最新資訊28at.com

Fzp28資訊網——每日最新資訊28at.com

在滾動的過程中,當前選中狀態會自動變化到對應的位置。接下來我們思考一下這樣的功能應該如何實現。Fzp28資訊網——每日最新資訊28at.com

本案例具體要實現的效果如圖:Fzp28資訊網——每日最新資訊28at.com

Fzp28資訊網——每日最新資訊28at.com

三、實現

實現原理比較簡單,我們只需要判斷每個元素什么時候應該出現在屏幕中即可。對于原生 DOM 而言,我們可以使用 getBoundingClientRect 來獲取元素對象在可視區域中的位置信息。Fzp28資訊網——每日最新資訊28at.com

本案例中的判斷規則非常簡單粗暴,因此當同屏出現兩個目標元素時會存在規則沖突,實踐中的規則設計會更細致一些,判斷邏輯也會更復雜。Fzp28資訊網——每日最新資訊28at.com

React 提供了 useRef 來獲取真實 DOM 對象。Fzp28資訊網——每日最新資訊28at.com

const n1 = useRef<HTMLDivElement>(null)... <div ref={n1}></div>

本案例中的主要內容為我們前面章節中搜索的 demo,因此每個 demo 都是使用 Block 組件來包裹布局。Fzp28資訊網——每日最新資訊28at.com

<Block className={s.container} title={td.title} desc={td.desc}>  <div className={r.flex}>    <input      className={s.input}      placeholder="請輸入您要搜索的內容"      onChange={(e) => setParam(e.target.value)}    />  </div>  <List    list={list}    loading={loading}    error={error}    renderItem={(item) => (      <div key={item} className={s.item}>{item}</div>    )}  /></Block>

但是因為 Block 并沒有針對 ref 進行支持,因此我們可以在外面額外套一個 div 作為目標元素。Fzp28資訊網——每日最新資訊28at.com

import Normal from './search/Normal'... <div ref={n1}>  <Normal /></div>

在頁面滾動的過程中,目標元素相對于可視區域的位置會隨時發生變化。因此我們可以在 effect 中添加 document 的滾動事件監聽。Fzp28資訊網——每日最新資訊28at.com

useEffect(() => {  document.addEventListener('scroll', () => {    ...  })}, [])

設計一個 state 狀態用來對應選中狀態。Fzp28資訊網——每日最新資訊28at.com

const [current, setCurrent] = useState(0)...<div className={current == 0 ? `${s.item} ${s.active}` : s.item}>案例一</div>

這樣,我們只需要在滾動過程中,不停的判斷每個目標元素和視口的相對位置,當符合條件的目標元素出現在視口時,就設置 current 為對應的值,功能就實現了。Fzp28資訊網——每日最新資訊28at.com

useEffect(() => {  document.addEventListener('scroll', () => {    const n1y = n1.current?.getBoundingClientRect().y    const n2y = n2.current?.getBoundingClientRect().y    const n3y = n3.current?.getBoundingClientRect().y    const n4y = n4.current?.getBoundingClientRect().y    const n5y = n5.current?.getBoundingClientRect().y    if (n1y > 0 && n1y < window.innerHeight) {      setCurrent(0)    }    if (n2y > 0 && n2y < window.innerHeight) {      setCurrent(1)    }    if (n3y > 0 && n3y < window.innerHeight) {      setCurrent(2)    }    if (n4y > 0 && n4y < window.innerHeight) {      setCurrent(3)    }    if (n5y > 0 && n5y < window.innerHeight) {      setCurrent(4)    }  })}, [])

當我們使用 ref 獲取真實 DOM 時,ref 可能會為 null,但是由于 effect 在組件渲染完成之后執行,此時必定能獲取到真實 DOM,因此我們使用 ?. 跳過了為 null 的判斷。Fzp28資訊網——每日最新資訊28at.com

const n1y = n1.current?.getBoundingClientRect().y

完整代碼如下:Fzp28資訊網——每日最新資訊28at.com

import { useEffect, useRef, useState } from 'react'import Normal from './search/Normal'import Normal2 from './search/Normal2'import Normal3 from './search/Normal3'import Normal4 from './search/Normal4'import Normal5 from './search/Normal5'import s from './style.module.scss'export default function EffectDemo() {  const [current, setCurrent] = useState(0)  const n1 = useRef<HTMLDivElement>(null)  const n2 = useRef<HTMLDivElement>(null)  const n3 = useRef<HTMLDivElement>(null)  const n4 = useRef<HTMLDivElement>(null)  const n5 = useRef<HTMLDivElement>(null)  useEffect(() => {    document.addEventListener('scroll', () => {      const n1y = n1.current?.getBoundingClientRect().y as number      const n2y = n2.current?.getBoundingClientRect().y as number      const n3y = n3.current?.getBoundingClientRect().y as number      const n4y = n4.current?.getBoundingClientRect().y as number      const n5y = n5.current?.getBoundingClientRect().y as number      if (n1y > 0 && n1y < window.innerHeight) {        setCurrent(0)      }      if (n2y > 0 && n2y < window.innerHeight) {        setCurrent(1)      }      if (n3y > 0 && n3y < window.innerHeight) {        setCurrent(2)      }      if (n4y > 0 && n4y < window.innerHeight) {        setCurrent(3)      }      if (n5y > 0 && n5y < window.innerHeight) {        setCurrent(4)      }    })  }, [])  return (    <div>      <div className={s.nav}>        <div className={current == 0 ? `${s.item} ${s.active}` : s.item}>案例一</div>        <div className={current == 1 ? `${s.item} ${s.active}` : s.item}>案例二</div>        <div className={current == 2 ? `${s.item} ${s.active}` : s.item}>案例三</div>        <div className={current == 3 ? `${s.item} ${s.active}` : s.item}>案例四</div>        <div className={current == 4 ? `${s.item} ${s.active}` : s.item}>案例五</div>      </div>      <div ref={n1}>        <Normal />      </div>      <div ref={n2}>        <Normal2 />      </div>            <div ref={n3}>        <Normal3 />      </div>      <div ref={n4}>        <Normal4 />      </div>            <div ref={n5}>        <Normal5 />      </div>          </div>  )}

四、總結

大量的初級框架開發者被困在「試圖讓框架解決所有問題」的思想牢籠里,認為學會了框架似乎就完事了。然而事實上,靈活運用 React 的 escape hatch 特性是成為 React 高手的標志之一,他在指引學習者不要把學習目標局限在 React 中,這是我們蛻變的開始。Fzp28資訊網——每日最新資訊28at.com

不要試圖讓 React 解決所有問題,讓他做擅長的事情。Fzp28資訊網——每日最新資訊28at.com

接下來我們思考兩個問題,一個問題是,在上面的案例中,我并沒有移除事件綁定,這樣的行為是否會造成內存泄露?第二個問題,我們期望封裝一個圖片組件,該組件需要支持懶加載的優化特性:只有當圖片內容進入到可視區域時,圖片才開始加載,這樣的圖片組件應該如何封裝?Fzp28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-55034-0.html蛻變之始,useEffect 最后一種用法

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 如何給自定義Python模塊自動生成文檔?

下一篇: 邏輯編程:上古人工智能語言Prolog

標簽:
  • 熱門焦點
  • K60至尊版剛預熱 一加Ace2 Pro正面硬剛

    Redmi這邊剛如火如荼的宣傳了K60 Ultra的各種技術和硬件配置,作為競品的一加也坐不住了。一加中國區總裁李杰發布了兩條微博,表示在自家的一加Ace2上早就已經采用了和PixelWo
  • 從 Pulsar Client 的原理到它的監控面板

    背景前段時間業務團隊偶爾會碰到一些 Pulsar 使用的問題,比如消息阻塞不消費了、生產者消息發送緩慢等各種問題。雖然我們有個監控頁面可以根據 topic 維度查看他的發送狀態,
  • 一文搞定Java NIO,以及各種奇葩流

    大家好,我是哪吒。很多朋友問我,如何才能學好IO流,對各種流的概念,云里霧里的,不求甚解。用到的時候,現百度,功能雖然實現了,但是為什么用這個?不知道。更別說效率問題了~下次再遇到,
  • 破圈是B站頭上的緊箍咒

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之每年的暑期檔都少不了瞄準追劇女孩們的古偶劇集,2021年有優酷的《山河令》,2022年有愛奇藝的《蒼蘭訣》,今年卻輪到小破站抓住了追
  • 東方甄選單飛:有些鳥注定是關不住的

    文/彭寬鴻編輯/羅卿東方甄選創始人俞敏洪帶隊的&ldquo;7天甘肅行&rdquo;直播活動已在近日順利收官。成立后一年多時間里,東方甄選要脫離抖音自立門戶的傳聞不絕于耳,&ldquo;7
  • 年輕人的“職場羞恥感”,無處不在

    作者:馮曉亭 陶 淘 李 欣 張 琳 馬舒葉來源:燃次元&ldquo;人在職場,應該選擇什么樣的著裝?&rdquo;近日,在網絡上,一個與著裝相關的帖子引發關注,在該帖子里,一位在高級寫字樓亞洲金
  • 阿里瓴羊One推出背后,零售企業迎數字化新解

    作者:劉曠近年來隨著數字經濟的高速發展,各式各樣的SaaS應用服務更是層出不窮,但本質上SaaS大多局限于單一業務流層面,對用戶核心關切的增長問題等則沒有提供更好的解法。在Saa
  • 華為和江淮汽車合作開發百萬元問界MPV?雙方回應來了

    8月1日消息,郭明錤今天在社交平臺發文稱,華為正在和江淮汽車合作,開發售價在100萬元的問界MPV,預計在2024年第2季度量產,銷量目標為上市首年交付5萬輛。
  • 朋友圈可以修改可見范圍了 蘋果用戶可率先體驗

    近日,iOS用戶迎來微信8.0.27正式版更新,除了可更換二維碼背景外,還新增了多項實用功能。在新版微信中,朋友圈終于可以修改可見范圍,簡單來說就是已發布的朋友圈
Top