阿川私房教材:學程式,拿 offer!

63 個專案實戰,直接上手!
無需補習,按步驟打造你的面試作品。

立即解鎖你的轉職秘笈

Hooks 是 React 最強大的功能之一。

它們使我們能夠輕鬆地在應用程式的元件中重用功能。掛鉤的最大優點在於它們的可重用性——您可以跨元件和專案重用掛鉤。

以下是我在每個 React 專案中重複使用的七個最重要的鉤子。今天就試一試,看看它們在建置您自己的 React 應用程式時是否有幫助吧。

原文出處:https://dev.to/webdevhero-com/7-react-hooks-for-every-project-1jdo


在我們開始之前,要先澄清一下:並非每個自定義 React 鉤子都需要由您編寫。事實上,我將提到的所有鉤子都來自一個庫“@mantine/hooks”。

Mantine 是一個很棒的第三方庫,其中包含這些鉤子等等。他們將為您的 React 應用程式加入您能想到的幾乎所有重要功能。

您可以在 mantine.dev 查看“@mantine/hooks”的文件。

useIntersection 鉤子

當用戶在您的應用程式中向下滾動頁面時,您可能想知道某個元素何時對他們可見。

例如,您可能希望僅在用戶看到特定元素時才啟動動畫。或者,您可能希望在他們向下滾動頁面一定程度後,顯示或隱藏元素。

use intersection

要獲取有關元素是否可見的訊息,我們可以使用 Intersection Observer API。這是瀏覽器中內建的 JavaScript API。

我們可以使用純 JavaScript 單獨使用 API,但要知道有關特定元素是否在其滾動容器內,有個好方法是使用 useIntersection 掛鉤。

import { useRef } from 'react';
import { useIntersection } from '@mantine/hooks';

function Demo() {
  const containerRef = useRef();
  const { ref, entry } = useIntersection({
    root: containerRef.current,
    threshold: 1,
  });

  return (
    <main ref={containerRef} style={{ overflowY: 'scroll', height: 300 }}>
      <div ref={ref}>
        <span>
          {entry?.isIntersecting ? 'Fully visible' : 'Obscured'}
        </span>
      </div>
    </main>
  );
}

要使用它,我們需要做的就是在我們的元件中呼叫鉤子,並提供一個根元素。 Root 是滾動容器,可以使用 useRef 掛鉤將其作為 ref 提供。 useIntersection 回傳一個我們傳遞給目標元素的 ref,我們想要觀察其在滾動容器中的交集。

一旦我們有了對元素的引用,我們就可以追蹤元素是否相交。在上面的範例中,我們可以根據 entry.isIntersecting 的值查看元素何時被遮擋或何時完全可見。

您可以傳遞其他參數,這些參數允許您配置與目標可見百分比相關的閾值

useScrollLock 鉤子

另一個與滾動相關的鉤子是 useScrollLock 鉤子。這個鉤子非常簡單:它使您能夠鎖定 body 元素上的任何滾動。

我發現當您想在當前頁面上顯示疊加層或跳出視窗,並且不想讓用戶在後台頁面上上下滾動時,它會很有幫助。這使您可以將注意力集中在視窗上,或允許在其自己的滾動容器內滾動。

import { useScrollLock } from '@mantine/hooks';
import { Button, Group } from '@mantine/core';
import { IconLock, IconLockOpen } from '@tabler/icons';

function Demo() {
  const [scrollLocked, setScrollLocked] = useScrollLock();

  return (
    <Group position="center">
      <Button
        onClick={() => setScrollLocked((c) => !c)}
        variant="outline"
        leftIcon={scrollLocked ? <IconLock size={16} /> : <IconLockOpen size={16} />}
      >
        {scrollLocked ? 'Unlock scroll' : 'Lock scroll'}
      </Button>
    </Group>
  );
}

useScrollLock 將用戶的滾動鎖定在頁面上的當前位置。該函數回傳一個陣列,它可以被解構,如上面的程式碼所示。

第二個值是一個允許我們鎖定滾動的函數。另一方面,第一個解構值是一個布林值,它告訴我們滾動條是否已被鎖定。

這個值很有用,例如,如果你想在滾動鎖定時顯示某些內容或告訴用戶它已被鎖定。您可以在下面的示例中看到,當滾動條被鎖定或解鎖時,我們會在我們的按鈕中進行指示。

use scroll lock

useClipboard 鉤子

在許多情況下,您希望提供一個按鈕,允許用戶將內容複製到他們的剪貼板,這是存儲複製文本的地方。

一個很好的例子是,如果您的網站上有一個程式碼片段,並且您希望用戶輕鬆複製它。為此,我們可以使用另一個 Web API——剪貼板 API

@mantine/hooks 為我們提供了一個方便的 useClipboard 鉤子,它回傳幾個屬性:copied,它是一個布林值,告訴我們是否已使用鉤子將值複製到剪貼板,以及copy 函數,我們可以將我們喜歡的任何字串值傳遞給它以進行複制。

在我們的範例中,我們想複製一個程式碼片段,供我們的用戶粘貼到他們喜歡的地方,如下面的影片所示:

使用剪貼板

useClipboard demo

當他們點擊我們指定的複制按鈕時,我們呼叫我們的 copy 函數,將程式碼片段傳遞給它,然後顯示一個小複選標記或向他們表明文本已被複製的東西。

巧妙的是 useClipboard 掛鉤帶有 超時值。在給定的超時時間(以毫秒為單位)之後,複製的狀態將被重置,向用戶顯示他們可以再次復製文本。

useDebouncedValue 鉤子

如果您的應用程式中有搜尋輸入,下一個鉤子“useDebouncedValue”是必不可少的。

每當用戶使用輸入執行搜尋時,搜尋操作通常涉及對 API 的 HTTP 請求。

您將遇到的一個典型問題是每次擊鍵都會執行查詢(請求),尤其是如果您希望用戶在鍵入時接收搜尋結果。即使對於一個簡單的搜尋查詢,也不需要在用戶完成輸入他們想要的內容之前執行這麼多請求。

這是 useDebounceValue 掛鉤的一個很好的用例,它對傳遞給它的文本應用「防抖」功能。

import { useState } from 'react';
import { useDebouncedValue } from '@mantine/hooks';
import { getResults } from 'api';

function Demo() {
  const [value, setValue] = useState('');
  const [results, setResults] = useState([])
  const [debounced] = useDebouncedValue(value, 200); // wait time of 200 ms

  useEffect(() => {
    if (debounced) {
      handleGetResults() 
    }

    async function handleGetResults() {
        const results = await getResults(debounced)   
        setResults(results)
    }
  }, [debounced])

  return (
    <>
      <input
        label="Enter search query"
        value={value}
        style={{ flex: 1 }}
        onChange={(event) => setValue(event.currentTarget.value)}
      />
      <ul>{results.map(result => <li>{result}</li>}</ul>
    </>
  );
}

您使用 useState 將輸入的文本儲存在一個狀態中,並將狀態變數傳遞給 useDebouncedValue 。

作為該掛鉤的第二個參數,您可以提供一個等待時間,即值被「反抖」的時間段。反抖使我們能夠執行更少的查詢。

您可以在下面的影片中看到結果,用戶在其中鍵入內容,並且僅在 200 毫秒後,我們才能看到去抖值。

使用去抖值

useMediaQuery 鉤子

我一直使用的另一個非常有用的鉤子是 useMediaQuery 鉤子。

Media Queries 在純 CSS 中使用,useMediaQuery 鉤子允許我們訂閱我們傳遞給鉤子的任何媒體查詢。

例如,在我們的元件中,假設我們想要顯示一些文本或根據特定螢幕寬度(例如 900 像素)更改元件的樣式。我們像在 CSS 中一樣提供媒體查詢,並且 useMediaQuery 回傳給我們一個 true 或 false 的 matches 值。

import { useMediaQuery } from '@mantine/hooks';

function Demo() {
  const matches = useMediaQuery('(min-width: 900px)');

  return (
    <div style={{ color: matches ? 'teal' : 'red' }}>
      {matches ? 'I am teal' : 'I am red'}
    </div>
  );
}

它用 JavaScript 告訴我們媒體查詢的結果,這在我們想要使用 style 屬性在 JSX 中直接更改樣式時特別有用,例如。

使用媒體查詢

簡而言之,對於少數無法使用 CSS 處理媒體查詢的情況,這是一個必不可少的鉤子。

useClickOutside 鉤子

下一個掛鉤 - useClickOutside - 可能看起來很奇怪,但當您真正需要它時,您會發現它的重要性。

當你開發一個下拉菜單,或者在頁面內容前面彈出,並且之後需要關閉的東西時,這個鉤子是必不可少的。通過單擊按鈕打開這些類型的元件之一非常容易。關閉這些元件有點困難。

為了遵循良好的 UX 實踐,我們希望任何阻礙用戶視圖的東西都可以通過單擊元素外部輕鬆關閉。這正是 useClickOutside 掛鉤讓我們做的。

當我們呼叫 useClickOutside 時,它會返回一個 ref,我們必須將其傳遞給我們想要檢測點擊的外部元素。通常該元素將由一個布林狀態片段控制,例如我們在下面的示例中的狀態(即值“opened”)。

import { useState } from 'react';
import { useClickOutside } from '@mantine/hooks';

function Demo() {
  const [opened, setOpened] = useState(false);
  const ref = useClickOutside(() => setOpened(false));

  return (
    <>
      <button onClick={() => setOpened(true)}>Open dropdown</button>
      {opened && (
        <div ref={ref} shadow="sm">
          <span>Click outside to close</span>
        </div>
      )}
    </>
  );
}

useClickOutside 接受一個回調函數,該函數控制當您實際單擊該元素外部時發生的情況。

在大多數情況下,我們想做一些非常簡單的事情,就是關閉它。為此,您可能需要一個狀態設置器(如 setOpened)並向其傳遞一個 false 值,然後隱藏您覆蓋的內容。

use click outside

useForm 鉤子

在這個列表中,我最喜歡和最有用的鉤子是 useForm 鉤子。

這個鉤子專門來自 Mantine,涉及從庫中安裝一個特定的包:@mantine/form。它會為您提供在 React 中建立表單所需的一切,包括驗證輸入、顯示錯誤訊息以及在提交表單之前確保輸入值正確的能力。

useForm 接受一些初始值,這些初始值對應於您在表單中的任何輸入。

import { TextInput, Button } from '@mantine/core';
import { useForm } from '@mantine/form';

function Demo() {
  const form = useForm({
    initialValues: {
      email: ''
    },

    validate: {
      email: (value) => (/^\S+@\S+$/.test(value) ? null : 'Invalid email'),
    },
  });

  return (
    <div>
      <form onSubmit={form.onSubmit((values) => console.log(values))}>
        <TextInput
          withAsterisk
          label="Email"
          placeholder="[email protected]"
          {...form.getInputProps('email')}
        />
        <Button type="submit">Submit</Button>
      </form>
    </div>
  );
}

useForm 的最大好處是它的助手,例如 validate 函數,它接收輸入到每個輸入的值,然後允許您建立驗證規則。

例如,如果您有一個電子郵件輸入,您可能有一個正則表達式來確定它實際上是否是一個有效的電子郵件(如您在上面的程式碼中所見)。如果沒有,那麼您可以顯示一條錯誤訊息並阻止提交表單。

使用表格

您如何獲取已輸入到表單中的值?

Mantine 提供了一個非常方便的助手,叫做“getInputProps”,你只需提供你正在使用的輸入的名稱(比如電子郵件),它就會自動設置一個 onChange 來追蹤你在表單中輸入的值.

此外,為了處理表單提交,並在其值未通過驗證規則時阻止送出,它有一個特殊的 onSubmit 函數,您可以將其包裹在常規的 onSubmit 函數中。除了應用驗證規則之外,它還會負責在表單事件上呼叫 preventDefault(),這樣您就不必手動執行此操作。

我只用了這個鉤子的基本功能,但我強烈建議您在下一個專案中使用它。傳統上,表單很難正常工作,尤其是需要驗證和可見錯誤訊息的表單。 useForm 讓它變得異常簡單!


以上,簡單分享,希望對您有幫助。


共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。

阿川私房教材:學程式,拿 offer!

63 個專案實戰,直接上手!
無需補習,按步驟打造你的面試作品。

立即解鎖你的轉職秘笈