日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
你應(yīng)該會(huì)喜歡的5個(gè)自定義Hook

文本已經(jīng)過原作者 Grégory D'Angelo 授權(quán)翻譯。

創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供猇亭網(wǎng)站建設(shè)、猇亭做網(wǎng)站、猇亭網(wǎng)站設(shè)計(jì)、猇亭網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、猇亭企業(yè)網(wǎng)站模板建站服務(wù),十年猇亭做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

React hooks

React hooks 已經(jīng)在16.8版本引入到庫中。它允許我們在函數(shù)組件中使用狀態(tài)和其他React特性,這樣我們甚至不需要再編寫類組件。

實(shí)際上,Hooks 遠(yuǎn)不止于此。

Hooks 可以將組件內(nèi)的邏輯組織成可重用的獨(dú)立單元。

Hooks 非常適合 React 組件模型和構(gòu)建應(yīng)用程序的新方法。Hooks 可以覆蓋類的所有用例,同時(shí)在整個(gè)應(yīng)用程序中提供更多的提取、測試和重用代碼的靈活性。

構(gòu)建自己的自定義React鉤子,可以輕松地在應(yīng)用程序的所有組件甚至不同應(yīng)用程序之間共享特性,這樣我們就不必重復(fù)自己的工作,從而提高構(gòu)建React應(yīng)用程序的效率。

現(xiàn)在,來看看我在開發(fā)中最常用的5個(gè)自定義鉤子,并頭開始重新創(chuàng)建它們,這樣你就能夠真正理解它們的工作方式,并確切地了解如何使用它們來提高生產(chǎn)率和加快開發(fā)過程。

我們直接開始創(chuàng)建我們的第一個(gè)自定義React Hooks。

useFetch

獲取數(shù)據(jù)是我每次創(chuàng)建React應(yīng)用時(shí)都會(huì)做的事情。我甚至在一個(gè)應(yīng)用程序中進(jìn)行了好多個(gè)這樣的重復(fù)獲取。

不管我們選擇哪種方式來獲取數(shù)據(jù),Axios、Fetch API,還是其他,我們很有可能在React組件序中一次又一次地編寫相同的代碼。

因此,我們看看如何構(gòu)建一個(gè)簡單但有用的自定義 Hook,以便在需要在應(yīng)用程序內(nèi)部獲取數(shù)據(jù)時(shí)調(diào)用該 Hook。

okk,這個(gè) Hook 我們叫它 useFetch。

這個(gè) Hook 接受兩個(gè)參數(shù),一個(gè)是獲取數(shù)據(jù)所需查詢的URL,另一個(gè)是表示要應(yīng)用于請(qǐng)求的選項(xiàng)的對(duì)象。

 
 
 
 
  1. import { useState, useEffect } from 'react'; 
  2.  
  3. const useFetch = (url = '', options = null) => {}; 
  4.  
  5. export default useFetch; 

獲取數(shù)據(jù)是一個(gè)副作用。因此,我們應(yīng)該使用useEffect Hook 來執(zhí)行查詢。

在本例中,我們使用 Fetch API來發(fā)出請(qǐng)求。我們會(huì)傳遞URL和 options。一旦 Promise 被解決,我們就通過解析響應(yīng)體來檢索數(shù)據(jù)。為此,我們使用json()方法。

然后,我們只需要將它存儲(chǔ)在一個(gè)React state 變量中。

 
 
 
 
  1. import { useState, useEffect } from 'react'; 
  2.  
  3. const useFetch = (url = '', options = null) => { 
  4.   const [data, setData] = useState(null); 
  5.  
  6.   useEffect(() => { 
  7.     fetch(url, options) 
  8.       .then(res => res.json()) 
  9.       .then(data => setData(data)); 
  10.   }, [url, options]); 
  11. }; 
  12.  
  13. export default useFetch; 

這里,我們還需要處理網(wǎng)絡(luò)錯(cuò)誤,以防我們的請(qǐng)求出錯(cuò)。所以我們要用另一個(gè) state 變量來存儲(chǔ)錯(cuò)誤。這樣我們就能從 Hook 中返回它并能夠判斷是否發(fā)生了錯(cuò)誤。

 
 
 
 
  1. import { useState, useEffect } from 'react'; 
  2.  
  3. const useFetch = (url = '', options = null) => { 
  4.   const [data, setData] = useState(null); 
  5.   const [error, setError] = useState(null); 
  6.  
  7.   useEffect(() => { 
  8.     fetch(url, options) 
  9.       .then(res => res.json()) 
  10.       .then(data => { 
  11.         if (isMounted) { 
  12.           setData(data); 
  13.           setError(null); 
  14.         } 
  15.       }) 
  16.       .catch(error => { 
  17.         if (isMounted) { 
  18.           setError(error); 
  19.           setData(null); 
  20.         } 
  21.       }); 
  22.   }, [url, options]); 
  23. }; 
  24.  
  25. export default useFetch; 

useFetch返回一個(gè)對(duì)象,其中包含從URL中獲取的數(shù)據(jù),如果發(fā)生了任何錯(cuò)誤,則返回錯(cuò)誤。

 
 
 
 
  1. return { error, data }; 

最后,向用戶表明異步請(qǐng)求的狀態(tài)通常是一個(gè)好做法,比如在呈現(xiàn)結(jié)果之前顯示 loading。

因此,我們添加第三個(gè) state 變量來跟蹤請(qǐng)求的狀態(tài)。在請(qǐng)求之前,將loading設(shè)置為true,并在請(qǐng)求之后完成后設(shè)置為false。

 
 
 
 
  1. const useFetch = (url = '', options = null) => { 
  2.   const [data, setData] = useState(null); 
  3.   const [error, setError] = useState(null); 
  4.   const [loading, setLoading] = useState(false); 
  5.  
  6.   useEffect(() => { 
  7.     setLoading(true); 
  8.  
  9.     fetch(url, options) 
  10.       .then(res => res.json()) 
  11.       .then(data => { 
  12.         setData(data); 
  13.         setError(null); 
  14.       }) 
  15.       .catch(error => { 
  16.         setError(error); 
  17.         setData(null); 
  18.       }) 
  19.       .finally(() => setLoading(false)); 
  20.   }, [url, options]); 
  21.  
  22.   return { error, data }; 
  23. }; 

現(xiàn)在,我們可以返回 loading 變量,以便在請(qǐng)求運(yùn)行時(shí)在組件中使用它來呈現(xiàn)一個(gè) loading,方便用戶知道我們正在獲取他們所請(qǐng)求的數(shù)據(jù)。

 
 
 
 
  1. return { loading, error, data }; 

在使用 userFetch 之前,我們還有一件事。

我們需要檢查使用我們 Hook 的組件是否仍然被掛載,以更新我們的狀態(tài)變量。否則,會(huì)有內(nèi)存泄漏。

 
 
 
 
  1. import { useState, useEffect } from 'react'; 
  2.  
  3. const useFetch = (url = '', options = null) => { 
  4.   const [data, setData] = useState(null); 
  5.   const [error, setError] = useState(null); 
  6.   const [loading, setLoading] = useState(false); 
  7.  
  8.   useEffect(() => { 
  9.     let isMounted = true; 
  10.  
  11.     setLoading(true); 
  12.  
  13.     fetch(url, options) 
  14.       .then(res => res.json()) 
  15.       .then(data => { 
  16.         if (isMounted) { 
  17.           setData(data); 
  18.           setError(null); 
  19.         } 
  20.       }) 
  21.       .catch(error => { 
  22.         if (isMounted) { 
  23.           setError(error); 
  24.           setData(null); 
  25.         } 
  26.       }) 
  27.       .finally(() => isMounted && setLoading(false)); 
  28.  
  29.     return () => (isMounted = false); 
  30.   }, [url, options]); 
  31.  
  32.   return { loading, error, data }; 
  33. }; 
  34.  
  35. export default useFetch; 

接下就是怎么用了?

我們只需要傳遞我們想要檢索的資源的URL。從那里,我們得到一個(gè)對(duì)象,我們可以使用它來渲染我們的應(yīng)用程序。

 
 
 
 
  1. import useFetch from './useFetch'; 
  2.  
  3. const App = () => { 
  4.   const { loading, error, data = [] } = useFetch( 
  5.     'https://hn.algolia.com/api/v1/search?query=react' 
  6.   ); 
  7.  
  8.   if (error) return 

    Error!

  9.   if (loading) return 

    Loading...

  10.  
  11.   return ( 
  12.     
     
  13.       
       
    •         {data?.hits?.map(item => ( 
    •            
    •             {item.title} 
    •           
    •  
    •         ))} 
    •       
     
  14.     
 
  •   ); 
  • }; 
  •  useEventListener

    這個(gè) Hook 負(fù)責(zé)在組件內(nèi)部設(shè)置和清理事件監(jiān)聽器。

    這樣,我們就不需要每次添加事件監(jiān)聽器,做重復(fù)的工作。

    這個(gè)函數(shù)有幾個(gè)參數(shù),eventType 事件類型,listener 監(jiān)聽函數(shù),target 監(jiān)聽對(duì)象,options 可選參數(shù)。

     
     
     
     
    1. import { useEffect, useRef } from 'react'; 
    2.  
    3. const useEventListener = ( 
    4.   eventType = '', 
    5.   listener = () => null, 
    6.   target = null, 
    7.   options = null 
    8. ) => {}; 
    9.  
    10. export default useEventListener; 

    與前一個(gè) Hook 一樣,用 useEffect 來添加一個(gè)事件監(jiān)聽器。首先,我們需要確保target 是否支持addEventListener方法。否則,我們什么也不做。

     
     
     
     
    1. import { useEffect, useRef } from 'react'; 
    2.  
    3. const useEventListener = ( 
    4.   eventType = '', 
    5.   listener = () => null, 
    6.   target = null, 
    7.   options = null 
    8. ) => { 
    9.  
    10.   useEffect(() => { 
    11.     if (!target?.addEventListener) return; 
    12.   }, [target]); 
    13. }; 
    14.  
    15. export default useEventListener; 

    然后,我們可以添加實(shí)際的事件監(jiān)聽器并在卸載函數(shù)中刪除它。

     
     
     
     
    1. import { useEffect, useRef } from 'react'; 
    2.  
    3. const useEventListener = ( 
    4.   eventType = '', 
    5.   listener = () => null, 
    6.   target = null, 
    7.   options = null 
    8. ) => { 
    9.   useEffect(() => { 
    10.     if (!target?.addEventListener) return; 
    11.  
    12.     target.addEventListener(eventType, listener, options); 
    13.  
    14.     return () => { 
    15.       target.removeEventListener(eventType, listener, options); 
    16.     }; 
    17.   }, [eventType, target, options, listener]); 
    18. }; 
    19.  
    20. export default useEventListener; 

    實(shí)際上,我們也會(huì)使用一個(gè)引用對(duì)象來存儲(chǔ)和持久化監(jiān)聽器函數(shù)。只有當(dāng)監(jiān)聽器函數(shù)發(fā)生變化并在事件監(jiān)聽器方法中使用該引用時(shí),我們才會(huì)更新該引用。

     
     
     
     
    1. import { useEffect, useRef } from 'react'; 
    2.  
    3. const useEventListener = ( 
    4.   eventType = '', 
    5.   listener = () => null, 
    6.   target = null, 
    7.   options = null 
    8. ) => { 
    9.   const savedListener = useRef(); 
    10.  
    11.   useEffect(() => { 
    12.     savedListener.current = listener; 
    13.   }, [listener]); 
    14.  
    15.   useEffect(() => { 
    16.     if (!target?.addEventListener) return; 
    17.  
    18.     const eventListener = event => savedListener.current(event); 
    19.  
    20.     target.addEventListener(eventType, eventListener, options); 
    21.  
    22.     return () => { 
    23.       target.removeEventListener(eventType, eventListener, options); 
    24.     }; 
    25.   }, [eventType, target, options]); 
    26. }; 
    27.  
    28. export default useEventListener; 

    我們不需要從此 Hook 返回任何內(nèi)容,因?yàn)槲覀冎皇莻陕犑录⑦\(yùn)行處理程序函數(shù)傳入作為參數(shù)。

    現(xiàn)在,很容易將事件偵聽器添加到我們的組件(例如以下組件)中,以檢測DOM元素外部的點(diǎn)擊。如果用戶單擊對(duì)話框組件,則在此處關(guān)閉對(duì)話框組件。

     
     
     
     
    1. import { useRef } from 'react'; 
    2. import ReactDOM from 'react-dom'; 
    3. import { useEventListener } from './hooks'; 
    4.  
    5. const Dialog = ({ show = false, onClose = () => null }) => { 
    6.   const dialogRef = useRef(); 
    7.  
    8.   // Event listener to close dialog on click outside element 
    9.   useEventListener( 
    10.     'mousedown', 
    11.     event => { 
    12.       if (event.defaultPrevented) { 
    13.         return; // Do nothing if the event was already processed 
    14.       } 
    15.       if (dialogRef.current && !dialogRef.current.contains(event.target)) { 
    16.         console.log('Click outside detected -> closing dialog...'); 
    17.         onClose(); 
    18.       } 
    19.     }, 
    20.     window 
    21.   ); 
    22.  
    23.   return show 
    24.     ? ReactDOM.createPortal( 
    25.          
    26.           
    27.             className="relative bg-white rounded-md shadow-card max-h-full max-w-screen-sm w-full animate-zoom-in px-6 py-20" 
    28.             ref={dialogRef} 
    29.           > 
    30.              
    31.               What's up{' '} 
    32.                
    33.                 YouTube 
    34.                
    35.               ? 
    36.             

       
    37.           
     
  •         
  •         document.body 
  •       ) 
  •     : null; 
  • }; 
  •  
  • export default Dialog; 
  •  useLocalStorage

    這個(gè) Hook 主要有兩個(gè)參數(shù),一個(gè)是 key,一個(gè)是 value。

     
     
     
     
    1. import { useState } from 'react'; 
    2.  
    3. const useLocalStorage = (key = '', initialValue = '') => {}; 
    4.  
    5. export default useLocalStorage;  

    然后,返回一個(gè)數(shù)組,類似于使用 useState 獲得的數(shù)組。因此,此數(shù)組將包含有狀態(tài)值和在將其持久存儲(chǔ)在localStorage 中時(shí)對(duì)其進(jìn)行更新的函數(shù)。

    首先,我們創(chuàng)建將與 localStorage 同步的React狀態(tài)變量。

     
     
     
     
    1. import { useState } from 'react'; 
    2.  
    3. const useLocalStorage = (key = '', initialValue = '') => { 
    4.   const [state, setState] = useState(() => { 
    5.     try { 
    6.       const item = window.localStorage.getItem(key); 
    7.       return item ? JSON.parse(item) : initialValue; 
    8.     } catch (error) { 
    9.       console.log(error); 
    10.       return initialValue; 
    11.     } 
    12.   }); 
    13. }; 
    14.  
    15. export default useLocalStorage; 

    在這里,我們使用惰性初始化來讀取 localStorage 以獲取鍵的值,如果找到該值,則解析該值,否則返回傳入的initialValue。

    如果在讀取 localStorage 時(shí)出現(xiàn)錯(cuò)誤,我們只記錄一個(gè)錯(cuò)誤并返回初始值。

    最后,我們需要?jiǎng)?chuàng)建 update 函數(shù)來返回它將在localStorage 中存儲(chǔ)任何狀態(tài)的更新,而不是使用useState 返回的默認(rèn)更新。

     
     
     
     
    1. import { useState } from 'react'; 
    2.  
    3. const useLocalStorage = (key = '', initialValue = '') => { 
    4.   const [state, setState] = useState(() => { 
    5.     try { 
    6.       const item = window.localStorage.getItem(key); 
    7.       return item ? JSON.parse(item) : initialValue; 
    8.     } catch (error) { 
    9.       return initialValue; 
    10.     } 
    11.   }); 
    12.  
    13.   const setLocalStorageState = newState => { 
    14.     try { 
    15.       const newStateValue = 
    16.         typeof newState === 'function' ? newState(state) : newState; 
    17.       setState(newStateValue); 
    18.       window.localStorage.setItem(key, JSON.stringify(newStateValue)); 
    19.     } catch (error) { 
    20.       console.error(`Unable to store new value for ${key} in localStorage.`); 
    21.     } 
    22.   }; 
    23.  
    24.   return [state, setLocalStorageState]; 
    25. }; 
    26.  
    27. export default useLocalStorage; 

    此函數(shù)同時(shí)更新React狀態(tài)和 localStorage 中的相應(yīng)鍵/值。這里,我們還可以支持函數(shù)更新,例如常規(guī)的useState hook。

    最后,我們返回狀態(tài)值和我們的自定義更新函數(shù)。

    現(xiàn)在可以使用useLocalStorage hook 將組件中的任何數(shù)據(jù)持久化到localStorage中。

     
     
     
     
    1. import { useLocalStorage } from './hooks'; 
    2.  
    3. const defaultSettings = { 
    4.   notifications: 'weekly', 
    5. }; 
    6.  
    7. function App() { 
    8.   const [appSettings, setAppSettings] = useLocalStorage( 
    9.     'app-settings', 
    10.     defaultSettings 
    11.   ); 
    12.  
    13.   return ( 
    14.      
    15.        
    16.         Your application's settings:

       
    17.  
    18.         
    19.           value={appSettings.notifications} 
    20.           onChange={e => 
    21.             setAppSettings(settings => ({ 
    22.               ...settings, 
    23.               notifications: e.target.value, 
    24.             })) 
    25.           } 
    26.           className="border border-gray-900 rounded py-2 px-4 " 
    27.         > 
    28.           daily 
    29.           weekly 
    30.           monthly 
    31.          
    32.       
     
  •  
  •       
  •         onClick={() => setAppSettings(defaultSettings)} 
  •         className="rounded-md shadow-md py-2 px-6 bg-red-500 text-white uppercase font-medium tracking-wide text-sm leading-8" 
  •       > 
  •         Reset settings 
  •        
  •     
  •  
  •   ); 
  •  
  • export default App; 
  •  useMediaQuery

    這個(gè) Hook 幫助我們在功能組件中以編程方式測試和監(jiān)控媒體查詢。這是非常有用的,例如,當(dāng)你需要渲染不同的UI取決于設(shè)備的類型或特定的特征。

    我們的 Hook 接受3個(gè)參數(shù):

    • 首先,對(duì)應(yīng)媒體查詢的字符串?dāng)?shù)組
    • 然后,以與前一個(gè)數(shù)組相同的順序匹配這些媒體查詢的值數(shù)組
    • 最后,如果沒有匹配的媒體查詢,則使用默認(rèn)值
     
     
     
     
    1. import { useState, useCallback, useEffect } from 'react'; 
    2.  
    3. const useMediaQuery = (queries = [], values = [], defaultValue) => {}; 
    4.  
    5. export default useMediaQuery; 

    我們在這個(gè) Hook 中做的第一件事是為每個(gè)匹配的媒體查詢構(gòu)建一個(gè)媒體查詢列表。使用這個(gè)數(shù)組通過匹配媒體查詢來獲得相應(yīng)的值。

     
     
     
     
    1. import { useState, useCallback, useEffect } from 'react'; 
    2.  
    3. const useMediaQuery = (queries = [], values = [], defaultValue) => { 
    4.   const mediaQueryList = queries.map(q => window.matchMedia(q)); 
    5. }; 
    6.  
    7. export default useMediaQuery; 

    為此,我們創(chuàng)建了一個(gè)包裝在useCallback 中的回調(diào)函數(shù)。檢索列表中第一個(gè)匹配的媒體查詢的值,如果沒有匹配則返回默認(rèn)值。

     
     
     
     
    1. import { useState, useCallback, useEffect } from 'react'; 
    2.  
    3. const useMediaQuery = (queries = [], values = [], defaultValue) => { 
    4.   const mediaQueryList = queries.map(q => window.matchMedia(q)); 
    5.  
    6.   const getValue = useCallback(() => { 
    7.     const index = mediaQueryList.findIndex(mql => mql.matches); 
    8.     return typeof values[index] !== 'undefined' ? values[index] : defaultValue; 
    9.   }, [mediaQueryList, values, defaultValue]); 
    10. }; 
    11.  
    12. export default useMediaQuery; 

    然后,我們創(chuàng)建一個(gè)React狀態(tài)來存儲(chǔ)匹配的值,并使用上面定義的函數(shù)來初始化它。

     
     
     
     
    1. import { useState, useCallback, useEffect } from 'react'; 
    2.  
    3. const useMediaQuery = (queries = [], values = [], defaultValue) => { 
    4.   const mediaQueryList = queries.map(q => window.matchMedia(q)); 
    5.  
    6.   const getValue = useCallback(() => { 
    7.     const index = mediaQueryList.findIndex(mql => mql.matches); 
    8.     return typeof values[index] !== 'undefined' ? values[index] : defaultValue; 
    9.   }, [mediaQueryList, values, defaultValue]); 
    10.  
    11.   const [value, setValue] = useState(getValue); 
    12. }; 
    13.  
    14. export default useMediaQuery; 

    最后,我們在 useEffect 中添加一個(gè)事件監(jiān)聽器來監(jiān)聽每個(gè)媒體查詢的更改。當(dāng)發(fā)生變化時(shí),我們運(yùn)行更新函數(shù)。

     
     
     
     
    1. mport { useState, useCallback, useEffect } from 'react'; 
    2.  
    3. const useMediaQuery = (queries = [], values = [], defaultValue) => { 
    4.   const mediaQueryList = queries.map(q => window.matchMedia(q)); 
    5.  
    6.   const getValue = useCallback(() => { 
    7.     const index = mediaQueryList.findIndex(mql => mql.matches); 
    8.     return typeof values[index] !== 'undefined' ? values[index] : defaultValue; 
    9.   }, [mediaQueryList, values, defaultValue]); 
    10.  
    11.   const [value, setValue] = useState(getValue); 
    12.  
    13.   useEffect(() => { 
    14.     const handler = () => setValue(getValue); 
    15.     mediaQueryList.forEach(mql => mql.addEventListener('change', handler)); 
    16.  
    17.     return () => 
    18.       mediaQueryList.forEach(mql => mql.removeEventListener('change', handler)); 
    19.   }, [getValue, mediaQueryList]); 
    20.  
    21.   return value; 
    22. }; 
    23.  
    24. export default useMediaQuery; 

    我最近使用的一個(gè)簡單的例子是添加一個(gè)媒體查詢來檢查設(shè)備是否允許用戶懸停在元素上。這樣,如果用戶可以懸停或應(yīng)用基本樣式,我就可以添加特定的不透明樣式。

     
     
     
     
    1. import { useMediaQuery } from './hooks'; 
    2.  
    3. function App() { 
    4.   const canHover = useMediaQuery( 
    5.     // Media queries 
    6.     ['(hover: hover)'], 
    7.     // Values corresponding to the above media queries by array index 
    8.     [true], 
    9.     // Default value 
    10.     false 
    11.   ); 
    12.  
    13.   const canHoverClass = 'opacity-0 hover:opacity-100 transition-opacity'; 
    14.   const defaultClass = 'opacity-100'; 
    15.  
    16.   return ( 
    17.     Hover me!
     
  •   ); 
  •  
  • export default App; 
  •  useDarkMode

    這個(gè)是我的最愛。它能輕松快速地將暗模式功能應(yīng)用于任何React應(yīng)用程序。

    這個(gè) Hook 主要按需啟用和禁用暗模式,將當(dāng)前狀態(tài)存儲(chǔ)在localStorage 中。

    為此,我們將使用我們剛剛構(gòu)建的兩個(gè)鉤子:useMediaQuery和useLocalStorage。

    然后,使用“ useLocalStorage”,我們可以在localStorage中初始化,存儲(chǔ)和保留當(dāng)前狀態(tài)(暗或亮模式)。

     
     
     
     
    1. import { useEffect } from 'react'; 
    2. import useMediaQuery from './useMediaQuery'; 
    3. import useLocalStorage from './useLocalStorage'; 
    4.  
    5. const useDarkMode = () => { 
    6.   const preferDarkMode = useMediaQuery( 
    7.     ['(prefers-color-scheme: dark)'], 
    8.     [true], 
    9.     false 
    10.   ); 
    11. }; 
    12.  
    13. export default useDarkMode; 

    最后一部分是觸發(fā)副作用,以向document.body元素添加或刪除dark類。這樣,我們可以簡單地將dark樣式應(yīng)用于我們的應(yīng)用程序。

     
     
     
     
    1. import { useEffect } from 'react'; 
    2. import useMediaQuery from './useMediaQuery'; 
    3. import useLocalStorage from './useLocalStorage'; 
    4.  
    5. const useDarkMode = () => { 
    6.   const preferDarkMode = useMediaQuery( 
    7.     ['(prefers-color-scheme: dark)'], 
    8.     [true], 
    9.     false 
    10.   ); 
    11.  
    12.   const [enabled, setEnabled] = useLocalStorage('dark-mode', preferDarkMode); 
    13.  
    14.   useEffect(() => { 
    15.     if (enabled) { 
    16.       document.body.classList.add('dark'); 
    17.     } else { 
    18.       document.body.classList.remove('dark'); 
    19.     } 
    20.   }, [enabled]); 
    21.  
    22.   return [enabled, setEnabled]; 
    23. }; 
    24.  
    25. export default useDarkMode; 

     ~完,我是小智,我要去刷碗了。

    作者:Grégory D'Angelo 譯者:前端小智 來源: dev原文:https://dev.to/alterclass/5-react-custom-hooks-you-should-start-using-explained-5d18


    分享名稱:你應(yīng)該會(huì)喜歡的5個(gè)自定義Hook
    瀏覽路徑:http://www.dlmjj.cn/article/cdgcdgi.html