中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React如何從Class方式轉Hooks

發布時間:2021-09-30 09:13:12 來源:億速云 閱讀:211 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“React如何從Class方式轉Hooks”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“React如何從Class方式轉Hooks”這篇文章吧。

    Why Hooks ?

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

    For Class
    • 使用Class作為React的載體的時候:

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

    For Function

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

    • Hooks怎樣去解決上面兩個問題:把一個外部的數據綁定到函數的執行。當數據變化時,讓函數能夠自動重新執行。這樣的話,任何會影響 UI 展現的外部數據,都可以通過這個機制綁定到 React 的函數組件。

    • Hooks鉤子的理解:把某個目標結果鉤到某個可能會變化的數據源或者事件源上,那么當被鉤到的數據或事件發生變化時,產生這個目標結果的代碼會重新執行,產生更新后的結果

    React如何從Class方式轉Hooks

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

    Class & Hooks 對比
    • 比起 Class 組件,函數組件是更適合去表達 React 組件的執行的,因為它更符合 State => View 這樣的一個邏輯關系。但是因為缺少狀態、生命周期等機制,讓它一直功能受限。Hooks解決了函數組件作為React載體的狀態生命周期等受限問題,讓其功能充分發揮出來

    • Hooks 中被鉤的對象,可以是某個獨立的數據源,也可以是另一個 Hook 執行的結果,這就帶來了 Hooks 的最大好處:邏輯的復用

    • 簡化了邏輯復用

      • Class方式中:使用高階組件的設計模式進行邏輯復用。比如:我們要去復用一個窗口resize的功能,我們需要去定義一個沒有UI的外層組件,去寫相關resize的邏輯定義,然后將數據結果用屬性的方式傳給子組件。組件要復用這個邏輯的話,必須外層用這個組件包裹并返回。針對整個而言,**為了傳遞一個外部的狀態,我們不得不定義一個沒有 UI 的外層組件,而這個組件只是為了封裝一段可重用的邏輯。**頻繁使用,每一個高階組件的使用都會多一層節點,會給調試等帶來很大的負擔。

    //Class中高階組件實現resize方法復用
    //1、高階組件的聲明
    const withWindowSize = Component => {
      // 產生一個高階組件 WrappedComponent,只包含監聽窗口大小的邏輯
      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() {
          // 將窗口大小傳遞給真正的業務邏輯組件
          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 屬性傳遞給真正的業務組件
    export default withWindowSize(MyComponent);
    • Hooks方式中:實現resize的話,窗口大小只是外部的一個數據狀態。我們使用hooks方式對其封裝,只是將其變成了一個可以綁定的數據源,當窗口大小發生變化的時候,這個組件也會重新渲染代碼會更加簡潔直觀,并且不會產生額外的組件節點。

    //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;
    };
    //函數組件中使用這個hook
    const Demo = () => {
      const size = useWindowSize();
      if (size === "small") return <SmallComponent />;
      else return <LargeComponent />;
    };
    • 有助于關注分離

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

    React如何從Class方式轉Hooks

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

    Hooks如何保存組件狀態和使用生命周期?

    React一共提供了10個HooksuseStateuseEffectuseCallbackuseMemouseRefuseContext等等

    1、useState:讓函數具有維持狀態的能力

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

    • 從 props 傳遞過來的值。有時候 props 傳遞過來的值無法直接使用,而是要通過一定的計算后再在 UI 上展示,比如說排序。那么我們要做的就是每次用的時候,都重新排序一下,或者利用某些 cache 機制,而不是將結果直接放到 state 里。

    • 從 URL 中讀到的值。比如有時需要讀取 URL 中的參數,把它作為組件的一部分狀態。那么我們可以在每次需要用的時候從 URL 中讀取,而不是讀出來直接放到 state 里。

    • 從 cookie、localStorage 中讀取的值。通常來說,也是每次要用的時候直接去讀取,而不是讀出來后放到 state 里。

    2、useEffect:執行副作用

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

    使用useEffect應該注意的點:

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

    useEffect(()=>{
    	console.log('re-render')		//每次render完成一次后就執行
    })
    • 空數組作為依賴項,則只在首次執行時觸發,對應到 Class 組件就是 componentDidMount

    useEffect(()=>{
      console.log('did mount')		//相當于componentDidMount
    },[])
    • 可以返回一個函數,用在組件銷毀的時候做一些清理的操作

    const [size,setResize] = useState({})
    useEffect(()=>{
    	const handler = () => {
        setResize()
    	}
    	window.addEventListener('resize',handler)
    	return ()=>{
    		window.removeEventListener('resize',handler)
    	}
    },[])

    以上是“React如何從Class方式轉Hooks”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    迁安市| 湖口县| 商丘市| 乌苏市| 宾川县| 武陟县| 棋牌| 民权县| 黄骅市| 田阳县| 聂荣县| 固始县| 大理市| 康马县| 阜新市| 丰城市| 沾化县| 苍山县| 龙海市| 连江县| 丽水市| 天长市| 临汾市| 湘西| 鹤山市| 武冈市| 庄河市| 安平县| 达州市| 许昌县| 曲松县| 双牌县| 崇礼县| 黑水县| 汉沽区| 获嘉县| 岫岩| 明溪县| 资源县| 开远市| 怀仁县|