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

React從Class方式轉Hooks詳解

 更新時間:2021年09月29日 16:53:31   作者:Vicky沛沛  
這篇文章主要介紹了React從Class方式轉Hooks詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

React Hooks

前言

之前工作三年中一直在用class方式去寫前端功能頁面這些,其實接觸hooks也是有一定時間了。在第一次接觸的時候應該是看了一門關于electron+react的項目的課程的時候。當時主要是去看electron,所以對hooks沒有特別的關注。也有可能是長期以來對class的熟悉,當時對hooks這種函數(shù)式的寫法也有一些抵觸。但是由于業(yè)內對hooks的好評,曾經(jīng)也想去用hooks去起一個項目,但是由于當時項目周期以及已有的技術棧等原因,一直想實踐也沒機會去實踐使用。

由于,最近接手新的項目一直使用的是react hooks+ts這一套。于是,就得開始使用hooks了。其實就功能開發(fā)而言,照貓畫虎,其實工作也沒有什么問題的。但是由于一直沒有系統(tǒng)的對hooks進行深入一步的了解,導致在很多時候,其實并不是很清楚為什么要這樣去使用,于是最近去找了《React Hooks核心原理與實戰(zhàn)》去進行了學習。

在使用層面以及原因層面上,重新審視hooks的使用以及為什么要使用hooks。函數(shù)式寫法究竟有哪些好處進行了更進一步的思考。其實,在一定程度而言,也還是淺嘗輒止,這里僅僅將我這段時間學習記錄下來。

Why Hooks ?

Hooks很大的一個亮點是可以進行業(yè)務邏輯的重用。這一點在hooks中體現(xiàn)的尤為明顯。比如,往常的class中如果要去監(jiān)聽窗口大小的變化的時候,就得在組件中在掛載后去添加監(jiān)聽事件,但是如果當另外一個地方需要用到這種監(jiān)聽窗口大小功能的話,這種邏輯代碼并不可以復用,只能在那個組件中重新寫一遍。但是在hooks中,我們可以將這部分監(jiān)聽的邏輯代碼進行hooks方式封裝,完全可以做到邏輯上的復用。

For Class

  • 使用Class作為React的載體的時候:
  • 組件之間不會相互繼承,沒有利用到class的繼承的特性UI是狀態(tài)驅動的,所有的方法都是內部調用或者作為生命周期的方法內部自動調用。沒有使用到類的實例方法可以調用的特性

For Function

React中的一個核心就是要實現(xiàn)從State數(shù)據(jù)到View試圖層面的一個綁定。使用函數(shù),其實更好的去解決State到View的一個映射問題。但是,用函數(shù)作為React的載體就會出現(xiàn)兩個問題,函數(shù)中狀態(tài)的保存以及生命周期的方法。

  • Hooks怎樣去解決上面兩個問題:把一個外部的數(shù)據(jù)綁定到函數(shù)的執(zhí)行。當數(shù)據(jù)變化時,讓函數(shù)能夠自動重新執(zhí)行。這樣的話,任何會影響 UI 展現(xiàn)的外部數(shù)據(jù),都可以通過這個機制綁定到 React 的函數(shù)組件。
  • Hooks鉤子的理解:把某個目標結果鉤到某個可能會變化的數(shù)據(jù)源或者事件源上,那么當被鉤到的數(shù)據(jù)或事件發(fā)生變化時,產生這個目標結果的代碼會重新執(zhí)行,產生更新后的結果

圖解:一個執(zhí)行過程(Execution),例如是函數(shù)組件本身,可以綁定在(鉤在)傳統(tǒng)意義的 State,或者 URL,甚至可以是窗口的大小。這樣當 State、URL、窗口大小發(fā)生變化時,都會重新執(zhí)行某個函數(shù),產生更新后的結果。

Class & Hooks 對比

  • 比起 Class 組件,函數(shù)組件是更適合去表達 React 組件的執(zhí)行的,因為它更符合 State => View 這樣的一個邏輯關系。但是因為缺少狀態(tài)、生命周期等機制,讓它一直功能受限。Hooks解決了函數(shù)組件作為React載體的狀態(tài)生命周期等受限問題,讓其功能充分發(fā)揮出來
  • Hooks 中被鉤的對象,可以是某個獨立的數(shù)據(jù)源,也可以是另一個 Hook 執(zhí)行的結果,這就帶來了 Hooks 的最大好處:邏輯的復用
  • 簡化了邏輯復用
    • Class方式中:使用高階組件的設計模式進行邏輯復用。比如:我們要去復用一個窗口resize的功能,我們需要去定義一個沒有UI的外層組件,去寫相關resize的邏輯定義,然后將數(shù)據(jù)結果用屬性的方式傳給子組件。組件要復用這個邏輯的話,必須外層用這個組件包裹并返回。針對整個而言,**為了傳遞一個外部的狀態(tài),我們不得不定義一個沒有 UI 的外層組件,而這個組件只是為了封裝一段可重用的邏輯。**頻繁使用,每一個高階組件的使用都會多一層節(jié)點,會給調試等帶來很大的負擔。
//Class中高階組件實現(xiàn)resize方法復用
//1、高階組件的聲明
const withWindowSize = Component => {
  // 產生一個高階組件 WrappedComponent,只包含監(jiān)聽窗口大小的邏輯
  class WrappedComponent extends React.PureComponent {
    constructor(props) {
      super(props);
      this.state = {
        size: this.getSize()
      };
    }
    componentDidMount() {
      window.addEventListener("resize", this.handleResize); 
    }
    componentWillUnmount() {
      window.removeEventListener("resize", this.handleResize);
    }
    getSize() {
      return window.innerWidth > 1000 ? "large" :"small";
    }
    handleResize = ()=> {
      const currentSize = this.getSize();
      this.setState({
        size: this.getSize()
      });
    }
    render() {
      // 將窗口大小傳遞給真正的業(yè)務邏輯組件
      return <Component size={this.state.size} />;
    }
  }
  return WrappedComponent;
};
//2、組件MyComponent使用高階組件中的resize功能
class MyComponent extends React.Component{
  render() {
    const { size } = this.props;
    if (size === "small") return <SmallComponent />;
    else return <LargeComponent />;
  }
}
// 使用 withWindowSize 產生高階組件,用于產生 size 屬性傳遞給真正的業(yè)務組件
export default withWindowSize(MyComponent); 
  • Hooks方式中:實現(xiàn)resize的話,窗口大小只是外部的一個數(shù)據(jù)狀態(tài)。我們使用hooks方式對其封裝,只是將其變成了一個可以綁定的數(shù)據(jù)源,當窗口大小發(fā)生變化的時候,這個組件也會重新渲染代碼會更加簡潔直觀,并且不會產生額外的組件節(jié)點。
//Hooks中使用hooks方法進行resize邏輯復用
//定義useWindowSize這個hook
const getSize = () => {
  return window.innerWidth > 1000 ? "large" : "small";
}
const useWindowSize = () => {
  const [size, setSize] = useState(getSize());
  useEffect(() => {
  const handler = () => {
      setSize(getSize())
    };
    window.addEventListener('resize', handler);
    return () => {
      window.removeEventListener('resize', handler);
    };
  }, []);
  return size;
};
//函數(shù)組件中使用這個hook
const Demo = () => {
  const size = useWindowSize();
  if (size === "small") return <SmallComponent />;
  else return <LargeComponent />;
};
  • 有助于關注分離

Hooks能夠讓針對同一個業(yè)務邏輯的代碼盡可能聚合在一塊,在Class組件中不得不吧同一個業(yè)務邏輯代碼分散在類組件的不同的生命周期方法中

img

圖解:左側是 Class 組件,右側是函數(shù)組件結合 Hooks。藍色和黃色代表不同的業(yè)務功能

Hooks如何保存組件狀態(tài)和使用生命周期?

React一共提供了10個HooksuseState、useEffect、useCallbackuseMemo、useRefuseContext等等

1、useState:讓函數(shù)具有維持狀態(tài)的能力

我們要遵循的一個原則就是:state 中永遠不要保存可以通過計算得到的值,例如:

  • 從 props 傳遞過來的值。有時候 props 傳遞過來的值無法直接使用,而是要通過一定的計算后再在 UI 上展示,比如說排序。那么我們要做的就是每次用的時候,都重新排序一下,或者利用某些 cache 機制,而不是將結果直接放到 state 里。
  • 從 URL 中讀到的值。比如有時需要讀取 URL 中的參數(shù),把它作為組件的一部分狀態(tài)。那么我們可以在每次需要用的時候從 URL 中讀取,而不是讀出來直接放到 state 里。
  • 從 cookie、localStorage 中讀取的值。通常來說,也是每次要用的時候直接去讀取,而不是讀出來后放到 state 里。

2、useEffect:執(zhí)行副作用

副作用是指一段和當前執(zhí)行結果無關的代碼。比如說要修改函數(shù)外部的某個變量,要發(fā)起一個請求。形式:useEffect(callback, dependencies)。涵蓋了componentDidMountcomponentDidUpdatecomponentWillUnmount三個生命周期方法。簡而言之,useEffect 是每次組件 render 完后判斷依賴并執(zhí)行。

使用useEffect應該注意的點:

沒有依賴項,則每次 render 后都會重新執(zhí)行

useEffect(()=>{
	console.log('re-render')		//每次render完成一次后就執(zhí)行
})
  • 空數(shù)組作為依賴項,則只在首次執(zhí)行時觸發(fā),對應到 Class 組件就是 componentDidMount
useEffect(()=>{
  console.log('did mount')		//相當于componentDidMount
},[])
  • 可以返回一個函數(shù),用在組件銷毀的時候做一些清理的操作
const [size,setResize] = useState({})
useEffect(()=>{
	const handler = () => {
    setResize()
	}
	window.addEventListener('resize',handler)
	return ()=>{
		window.removeEventListener('resize',handler)
	}
},[])

總結

  • useEffect使用的四個場景 每次 render 后執(zhí)行:不提供第二個依賴項參數(shù)。比如useEffect(() => {})。
  • 僅第一次 render 后執(zhí)行:提供一個空數(shù)組作為依賴項。比如useEffect(() => {}, [])。
  • 第一次以及依賴項發(fā)生變化后執(zhí)行:提供依賴項數(shù)組。比如useEffect(() => {}, [deps])。
  • 組件 unmount 后執(zhí)行:返回一個回調函數(shù)。比如useEffect() => { return () => {} }, [])。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!

相關文章

  • 關于React Native報Cannot initialize a parameter of type''NSArray<id<RCTBridgeModule>>錯誤(解決方案)

    關于React Native報Cannot initialize a parameter of type''NSArra

    這篇文章主要介紹了關于React Native報Cannot initialize a parameter of type'NSArray<id<RCTBridgeModule>>錯誤,本文給大家分享解決方案,需要的朋友可以參考下
    2021-05-05
  • Rust中Trait的使用

    Rust中Trait的使用

    在Rust中,Trait是一個核心概念,它允許我們定義類型應該具有的行為,本文就來具體介紹一下Rust中Trait的使用,感興趣的可以了解一下,感興趣可以了解一下
    2024-03-03
  • vite?+?react?+typescript?環(huán)境搭建小白入門教程

    vite?+?react?+typescript?環(huán)境搭建小白入門教程

    這篇文章主要介紹了vite?+?react?+typescript?環(huán)境搭建小白入門教程,本文通過示例圖文相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • React跨路由組件動畫實現(xiàn)

    React跨路由組件動畫實現(xiàn)

    在 React 中路由之前的切換動畫可以使用 react-transition-group 來實現(xiàn),但對于不同路由上的組件如何做到動畫過渡是個很大的難題,目前社區(qū)中也沒有一個成熟的方案,本文給大家分享React跨路由組件動畫實現(xiàn),感興趣的朋友一起看看吧
    2023-10-10
  • react實現(xiàn)antd線上主題動態(tài)切換功能

    react實現(xiàn)antd線上主題動態(tài)切換功能

    這篇文章主要介紹了react實現(xiàn)antd線上主題動態(tài)切換功能,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-08-08
  • React 組件轉 Vue 組件的命令寫法

    React 組件轉 Vue 組件的命令寫法

    本文先介紹兩個框架的組件共性和不兼容的地方,再介紹react-to-vue的使用和原理,需要的朋友可以參考下
    2018-02-02
  • react基于Ant Desgin Upload實現(xiàn)導入導出

    react基于Ant Desgin Upload實現(xiàn)導入導出

    本文主要介紹了react基于Ant Desgin Upload實現(xiàn)導入導出,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • React使用highlight.js Clipboard.js實現(xiàn)代碼高亮復制

    React使用highlight.js Clipboard.js實現(xiàn)代碼高亮復制

    這篇文章主要為大家介紹了React使用highlight.js Clipboard.js實現(xiàn)代碼高亮復制功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • React18的useEffect執(zhí)行兩次如何應對

    React18的useEffect執(zhí)行兩次如何應對

    這篇文章主要給大家介紹了關于React18的useEffect執(zhí)行兩次如何應對的相關資料,文中通過實例代碼介紹的非常詳細,對大家學習或者使用React具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • 詳解React Native 屏幕適配(炒雞簡單的方法)

    詳解React Native 屏幕適配(炒雞簡單的方法)

    React Native 可以開發(fā) ios 和 android 的 app,在開發(fā)過程中,勢必會遇上屏幕適配,這篇文章主要介紹了詳解React Native 屏幕適配(炒雞簡單的方法),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06

最新評論

仁怀市| 百色市| 上栗县| 临澧县| 河曲县| 望城县| 桂林市| 望城县| 寿光市| 安乡县| 孟村| 八宿县| 潮安县| 内乡县| 卫辉市| 金湖县| 酒泉市| 福鼎市| 札达县| 潍坊市| 宜城市| 达拉特旗| 砚山县| 永泰县| 康马县| 乳源| 庆安县| 淮阳县| 临沧市| 南川市| 岗巴县| 正阳县| 将乐县| 阿克苏市| 宁海县| 汝城县| 射洪县| 淮南市| 藁城市| 伊宁市| 项城市|