React 提供了自定義 Hooks 的特性,咱們能夠根據這個特性建立出不少有意思的功能,今天就來分享一些我的認爲還不錯的 Hooks,共計 15 個。react
若是對於 React Hooks 還不是特別熟悉的話,能夠先參閱這篇文章:React Hooks 溫故而知新git
useClippy
是一個用來讀取或寫入粘貼板的自定義 Hook,支持 TypeScript。github
官方文檔:github.com/CharlesStov…npm
代碼示例:api
import useClippy from 'use-clippy';
export default () => {
const [clipboard, setClipboard] = useClippy();
return (
<div> <button onClick={() => { alert(`粘貼板內容爲: ${clipboard}`); }} > 讀取粘貼板 </button> <button onClick={() => { setClipboard(`新內容: ${Math.random()}`); }} > 寫入粘貼板 </button> </div>
);
};
複製代碼
useWindowSize
用於獲取瀏覽器窗口大小,默認按 debounce
方式獲取,固然也能夠以 throttled
方式獲取。瀏覽器
官方文檔:github.com/jaredLunde/…網絡
代碼示例:dom
import { useWindowSize } from '@react-hook/window-size';
// import { useWindowSize } from '@react-hook/window-size/throttled';
export default (props) => {
const [width, height] = useWindowSize();
return (
<div> width: {width}, height: {height} </div>
);
};
複製代碼
useMediaQuery
經過在組件中使用 CSS3 Media Query 來控制組件。異步
官方文檔:github.com/jaredLunde/…async
代碼示例:
import React from 'react';
import { useMediaQuery, useMediaQueries } from '@react-hook/media-query';
// Using a single media query
// export default () => {
// const matches = useMediaQuery('only screen and (min-width: 400px)');
// return `Matches? ${matches ? 'Matched!' : 'Nope'}`;
// };
// Using multiple media queries
export default () => {
const { matches, matchesAny, matchesAll } = useMediaQueries({
screen: 'screen',
width: '(min-width: 400px)',
});
return (
<ul> <li>Screen matched? {matches.screen ? 'Yes' : 'No'}</li> <li>Width matched? {matches.width ? 'Yes' : 'No'}</li> <li>All matched? {matchesAll ? 'Yes' : 'No'}</li> <li>Any matched? {matchesAny ? 'Yes' : 'No'}</li> </ul>
);
};
複製代碼
useAsync
用於優雅地解決、取消和處理異步函數或 Promise,而且當組件卸載時還能夠自動清除它們。
代碼示例:
import { useAsync } from '@react-hook/async';
export default () => {
const [{ status, cancel, error, value }, call] = useAsync(() => {
return new Promise((resolve) => setTimeout(() => resolve('Loaded'), 3000));
});
switch (status) {
case 'loading':
return (
<div> <button onClick={cancel}>Cancel</button> Loading... </div>
);
case 'cancelled':
return (
<div> Cancelled. <button onClick={call}>Try again</button> </div>
);
case 'error':
return `Error: ${error}`;
case 'success':
return value || 'Success!';
default:
return <button onClick={call}>Load me</button>;
}
};
複製代碼
useBrowserContextCommunication
使用 Broadcast Channel API 爲不一樣瀏覽器上下文(選項卡,iframe,窗口)之間的通訊提供簡單的解決方案。
代碼示例:
import useBrowserContextCommunication from 'react-window-communication-hook';
export default () => {
// communicationState 是一個 {lastMessage, messages} 對象,用於從其它的瀏覽器上下文接收數據
const [communicationState, postMessage] = useBrowserContextCommunication(
'channel'
);
const [status, setStatus] = useState('login');
function logout() {
setStatus('logout');
postMessage('logout');
}
const isLogout = [communicationState.lastMessage, status].includes('logout');
return (
<div> <h1>狀態:{isLogout ? '已退出' : '已登陸'}</h1> <button onClick={logout}>退出</button> </div>
);
};
複製代碼
能夠在瀏覽器裏打開兩個 Tab,而後在其中一個頁面點擊「退出」按鈕,會發現兩個 Tab 的頁面都發生了變化。
useScript
用於動態加載外部腳本,並提供了 onLoad
回調用於獲得腳本加載完成的時間。
代碼示例:
import { StripeProvider } from 'react-stripe-elements';
import useScript from 'react-script-hook';
export default () => {
const [loading, error] = useScript({ src: 'https://js.stripe.com/v3/' });
if (loading) return <h3>Loading Stripe API...</h3>;
if (error) return <h3>Failed to load Stripe API: {error.message}</h3>;
return (
<StripeProvider apiKey="pk_test_6pRNASCoBOKtIshFeQd4XMUh"> <div>Hello</div> </StripeProvider>
);
};
複製代碼
固然也能夠以回調函數的形式使用:
useScript({
src: 'https://js.stripe.com/v3/',
onload: () => console.log('Script loaded!')
})
複製代碼
useLocalStorage
用於經過 localStorage API 進行數據存取。
代碼示例:
import { useLocalStorage, writeStorage } from '@rehooks/local-storage';
let counter = 0;
export default () => {
const [counterData] = useLocalStorage('counter');
return (
<> {counter} <button onClick={() => writeStorage('counter', ++counter)}>Write</button> <button onClick={() => alert(counterData)}>Read</button> </> ); }; 複製代碼
useIdb
使用瀏覽器中的 IndexedDB
來存儲數據,跟 useLocalStorage
相似。
代碼示例:
import { useIdb } from 'react-use-idb';
export default () => {
const [value, setValue] = useIdb('my-key', 'foo');
return (
<div> <div>Value: {value}</div> <button onClick={() => setValue('bar')}>bar</button> <button onClick={() => setValue('baz')}>baz</button> </div>
);
};
複製代碼
use-mouse-action
用於監聽點擊事件時鼠標(也多是觸摸板)按下或彈起。
代碼示例:
import useMouseAction from 'use-mouse-action';
export default () => {
const props = useMouseAction({
onAction: () => console.log('You clicked or mouse downed me!'),
down: true,
});
return (
<button type="button" {...props}> Click me fast! </button>
);
};
複製代碼
useDebounce
用於延遲 setState
或者其它回調函數的執行。
代碼示例:
import {useDebounce, useDebounceCallback} from '@react-hook/debounce'
const Component = (props) => {
// at a basic level, used just like useState
const [value, setValue] = useDebounce('initialValue')
}
const useMyCallback = (initialState, wait, leading) => {
// this is the same code useDebounce() uses to debounce setState
const [state, setState] = useState(initialState)
return [state, useDebounceCallback(setState, wait, leading)]
}
複製代碼
useThrottle
用於稀釋 setState
或者其它回調函數的執行頻率。
代碼示例:
import {useThrottle, useThrottleCallback} from '@react-hook/throttle'
const Component = (props) => {
// at a basic level, used just like useState
const [value, setValue] = useThrottle('initialValue')
}
const useMyCallback = (initialState, fps, leading) => {
// this is the same code useThrottle() uses to throttle setState
const [state, setState] = useState(initialState)
return [state, useThrottleCallback(setState, fps, leading)]
}
複製代碼
useOnlineStatus
用於獲取當前的網絡狀態,內部經過監聽 online
及 offline
事件實現。
代碼示例:
import useOnlineStatus from '@rehooks/online-status';
export default () => {
const onlineStatus = useOnlineStatus();
return (
<div> <h1>You are {onlineStatus ? 'Online' : 'Offline'}</h1> </div>
);
};
複製代碼
useDocumentTitle
用於更新頁面標題。
代碼示例:
import useDocumentTitle from '@rehooks/document-title';
export default () => {
useDocumentTitle('Page Title');
return <div />; }; 複製代碼
useNetworkStatus
暴露了navigator.connection
對象,用於實時獲取網絡狀態。
代碼示例:
import useNetworkStatus from '@rehooks/network-status';
export default () => {
let connection = useNetworkStatus();
return (
<div> <div>downlink: {connection.downlink}</div> <div>effectiveType: {connection.effectiveType}</div> <div>rtt: {connection.rtt}</div> <div>saveData: {connection.saveData ? 'yes' : 'no'}</div> </div>
);
};
複製代碼
useSpeechSynthesis
經過使用 Web Speech API 提供了語音識別及文字轉語音的能力,還能夠識別中英文。
官方文檔:www.npmjs.com/package/rea… 在線示例:mikeyparton.github.io/react-speec…
代碼示例:
import { useSpeechSynthesis, useSpeechRecognition } from 'react-speech-kit';
export default () => {
const [value, setValue] = useState('');
const { speak } = useSpeechSynthesis();
const { listen, listening, stop } = useSpeechRecognition({
onResult: (result) => {
setValue(result);
},
});
return (
<div> <textarea value={value} onChange={(event) => setValue(event.target.value)} /> <br /> <button onMouseDown={listen} onMouseUp={stop}> Listen </button> <button onClick={() => speak({ text: value })}>Speak</button> {listening && <div>Go ahead I'm listening</div>} </div> ); }; 複製代碼
能夠按住 Listen
按鈕不放隨便說一句話,它會自動識別錄入到文本框裏,而後再點擊Speak
按鈕,它會自動識別文本框中的內容並語音播放。