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

詳解React自定義Hook

 更新時間:2023年04月21日 11:55:34   作者:Aphelios_  
在React項目中,我們經(jīng)常會使用到React自帶的幾個內(nèi)置Hooks,如 useState,useContext和useEffect。雖然在React中找不到這些 Hooks,但React提供了非常靈活的方式讓你為自己的需求來創(chuàng)建自己的自定義Hooks,想了解更多的,歡迎閱讀本文

前言

在 React 項目中,我們經(jīng)常會使用到 React 自帶的幾個內(nèi)置 Hooks,如 useState,useContext 和useEffect。但有時,我們可能希望有一個特定目的的 Hook :例如獲取數(shù)據(jù) useData,獲取連接 useConnect 等。雖然在 React 中找不到這些 Hooks,但 React 提供了非常靈活的方式讓你為自己的需求來創(chuàng)建自己的自定義 Hooks。

如何自定義 Hooks

在 React 中你必須遵循以下命名約定:

  • React Component: React 組件名稱必須以大寫字母開頭,如 StatusBar 和 SaveButton。React組件還需要 返回 一些React知道如何渲染的東西,比如 JSX 。

  • React Hook: Hook 名必須以 use 開頭,后面跟著一個大寫字母,比如 useState (內(nèi)置)或useStatus (自定義)。與 React 組件不同的是自定義 Hook 可以返回任意值

這個命名約定確保你始終可以查看組件,并了解其狀態(tài)、效果以及其他 React 特性可能“隱藏”的位置。例如,如果你在組件中看到 getColor() 函數(shù)調(diào)用,你可以確定它不可能包含 React state,因為其名稱不以use開頭。但是,像 useStatus() 這樣的函數(shù)調(diào)用很可能包含對其他 Hooks 的調(diào)用!

組件之間共享邏輯

The code inside them describes what they want to do rather than how to do it .

自定義 Hooks 的核心是共享組件之間的邏輯。使用自定義 Hooks 能夠減少重復(fù)的邏輯,更重要的是,自定義 Hooks 內(nèi)部的代碼描述了它們想做什么,而不是如何做。當(dāng)你將邏輯提取到自定義Hooks 中時,你可以隱藏如何處理某些"外部系統(tǒng)"或瀏覽器 API 的調(diào)用的細節(jié),組件的代碼表達的是你的意圖,而不是實現(xiàn)細節(jié)。 下面是一個簡單的例子:

import { useState } from 'react';
function useCounter(initialValue) {
  const [count, setCount] = useState(initialValue);
  function increment() {
    setCount(count + 1);
  }
  return [count, increment];
}

這個自定義 Hook 叫做 useCounter,它接受一個初始值作為參數(shù),并返回一個數(shù)組,包含當(dāng)前的計數(shù)值和一個增加計數(shù)的函數(shù)。 使用自定義 Hook 非常簡單,只需要在函數(shù)組件中調(diào)用它即可。下面是一個使用 useCounter 的例子:

import React from 'react';
import useCounter from './useCounter';

function Counter() {
  const [count, increment] = useCounter(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

在這個例子中,我們導(dǎo)入了 useCounter,并在組件中調(diào)用它。我們將返回的數(shù)組解構(gòu)為 count 和 increment,然后在組件中使用它們。

自定義 Hooks 允許你共享有狀態(tài)邏輯,而不是狀態(tài)本身

自定義 Hooks 允許共享有狀態(tài)邏輯,但不能共享狀態(tài)本身。每個對 Hook 的調(diào)用都完全獨立于對同一個 Hook 的其他調(diào)用。 以上面的 useCounter 為例:

import useCounter from './useCounter';
function Counter() {
	const [count1, increment1] = useCounter(0);
	const [count2, increment2] = useCounter(100);
  return (
    <div>
      <p>Count1: {count1}</p>
      <button onClick={increment1}>Increment1</button>
       <p>Count2: {count2}</p>
      <button onClick={increment2}>Increment2</button>
    </div>
  );
}

當(dāng)我們點擊 Increment2 時,并不會影響 count1 ,因為每一個 useCounter 的調(diào)用都是獨立的,其內(nèi)部狀態(tài)也是獨立的。

分類

功能型 Hooks

以實現(xiàn)特定功能或目的,與具體業(yè)務(wù)無關(guān):

useWindowWidth

該 hook 返回窗口寬度的值。

import { useState, useEffect } from 'react';
function useWindowWidth() {
  const [windowWidth, setWindowWidth] = useState(window.innerWidth);
  useEffect(() => {
    const handleResize = () => setWindowWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  return windowWidth;
}

useLocalStorage

該 hook 允許你在本地存儲中存儲和檢索值。

import { useState } from 'react';

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.log(error);
      return initialValue;
    }
  });

  const setValue = (value) => {
    try {
      setStoredValue(value);
      window.localStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.log(error);
    }
  };

  return [storedValue, setValue];
}

業(yè)務(wù)型 Hooks

useFetch

該 hook 允許你從 API 中獲取數(shù)據(jù)。

import { useState, useEffect } from 'react';
function useFetch(url) {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(url);
        const json = await response.json();
        setData(json);
      } catch (error) {
        setError(error);
      } finally {
        setIsLoading(false);
      }
    };
    fetchData();
  }, [url]);
  return { data, error, isLoading };
}

useModal

該 hook 允許你管理模態(tài)對話框的狀態(tài)。

//useFetch.js
import {useState, useEffect} from 'react'
//don't forget to give a url parameter for the function.
const useFetch = (url)=>{
  const [data, setData] = useState([])
  const getData = async ()=>{
    const response = await fetch(url)
    const userdata = await response.json()
    setData(userdata)
  }
 useEffect(()=>{
    getData()
  },[url])
  //return data that we will need in other components.
  return {data};
}
export default useFetch;

在多個 Hook 之間傳遞信息

由于 Hook 本身就是函數(shù),因此我們可以在它們之間傳遞信息。下面我們以 useUserInfo 獲取用戶信息 為例:

//useUserInfo.jsx
import { useEffect,useState } from 'react'
const useUserInfo = (userId) => {
  const [userInfo, setUserInfo] = useState({})
  useEffect(() => {
    fetch('/user')
      .then(res => res.json())
      .then(data => setUserInfo(data))
  }, [userId])
  return userInfo
}
//Home.jsx
...
const Home = ()=>{
	const [userId,setUserId] = useState('103')
	const useInfo = useUserInfo(userId)
	return (
	  <>
	     <div>name:{userInfo.name}</div>
	     <div>age:{userInfo.age}</div>
	     ...
	  </> 
	)
}

我們將 用戶 id 保存在 userId 狀態(tài)變量中,當(dāng)用戶進行某一操作 setUserId 時,由于 useState 為我們提供了 userId 狀態(tài)變量的最新值,因此我們可以將它作為參數(shù)傳遞給自定義的 useUserInfo Hook:

const [userId,setUserId] = useState('103')
const userInfo = useUserInfo(userId)

此時,我們的 userInfo 會隨著 userId 的改變而更新。

將 event handlers 傳遞給自定義 Hooks

This section describes an experimental API that has not yet been released in a stable version of React. 本節(jié)描述了一個尚未在 React 穩(wěn)定版本中發(fā)布的 實驗性 API。

你可能希望讓組件自定義其行為,而不是完全地將邏輯封裝 Hooks 中,我們可以通過將 event handlers 作為參數(shù)傳遞給 Hooks,下面是一個聊天室的例子: useChatRoom 接受一個服務(wù)端 url 和 roomId,當(dāng)調(diào)用這個 Hook 的時候,會進行連接,

export function useChatRoom({ serverUrl, roomId }) {
  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.connect();
    connection.on('message', (msg) => {
      showNotification('New message: ' + msg);
    });
    return () => connection.disconnect();
  }, [roomId, serverUrl]);
}

假設(shè)當(dāng)連接成功時,你想將此邏輯移回你的組件:

export default function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');
  useChatRoom({
    roomId: roomId,
    serverUrl: serverUrl,
    onReceiveMessage(msg) {
      showNotification('New message: ' + msg);
    }
  });
  // ...

要做到這一點,改變你的自定義 Hook ,把 onReceiveMessage 作為它的命名選項之一:

export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) {
  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.connect();
    connection.on('message', (msg) => {
      onReceiveMessage(msg);
    });
    return () => connection.disconnect();
  }, [roomId, serverUrl, onReceiveMessage]); // ? All dependencies declared
}

這可以工作,但是當(dāng)你的自定義 Hook 接受事件處理程序時,你還可以做一個改進。 在 onReceiveMessage 上添加依賴并不理想,因為它會導(dǎo)致每次組件重新渲染時聊天都重新連接。將此事件處理程序包裝到 EffectEvent 中以將其從依賴項中移除:

import { useEffect, useEffectEvent } from 'react';  
// ...
export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) {
  const onMessage = useEffectEvent(onReceiveMessage);
  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.connect();
    connection.on('message', (msg) => {
      onMessage(msg);
    });
    return () => connection.disconnect();
  }, [roomId, serverUrl]); // ? All dependencies declared
}

現(xiàn)在不會在每次重新渲染聊天室組件時進行重新連接。

開源 React Hooks 庫

  • ahooks 一套由阿里巴巴開源的 React Hooks 庫,封裝了大量好用的 Hooks。
  • react-use 一個必不可少的 React Hooks 集合。其包含了傳感器、用戶界面、動畫效果、副作用、生命周期、狀態(tài)這六大類的Hooks。
  • useHooks 一組易于理解的 React Hook集合。
  • react-recipes 一個包含流行的自定義 Hook 的 React Hooks 實用程序庫。
  • Rhooks 一組基本的 React 自定義Hooks。
  • react-hanger 一組有用的 hooks,用于特定于某些基本類型的狀態(tài)更改輔助函數(shù)。
  • Beautiful React Hook 一組漂亮的(希望有用的)React hooks 來加速你的組件和 hooks 開發(fā)。
  • Awesome React Hooks 一個很棒的 React Hooks 資源集合,該集合包含React Hooks教程、視頻、工具,Hooks列表。其中Hooks列表中包含了眾多實用的自定義Hooks。
  • SWR 一個用于獲取數(shù)據(jù)的 React Hooks 庫。只需一個Hook,就可以顯著簡化項目中的數(shù)據(jù)獲取邏輯。
  • React Hook Form 一個用于表單狀態(tài)管理和驗證的 React Hooks (Web + React Native)。

總結(jié)

自定義 Hooks 可以幫助你遷移到更好的開發(fā)范式。通過將一些通用邏輯封裝在自定義 Hooks 中,你可以使組件代碼保持簡潔專注于核心意圖,這有助于減少重復(fù)性的代碼,并使你的代碼更易于維護更新,從而使你能夠更快速地開發(fā)新功能。

對于 Effect 而言,這樣可以使數(shù)據(jù)在 Effects 中流動的過程變得非常明確。這讓你的組件能夠專注于意圖,而不是 Effects 的具體實現(xiàn)。當(dāng) React 添加新功能時,你可以刪除那些 Effects 而不影響任何組件。就像設(shè)計系統(tǒng)一樣,你可能會發(fā)現(xiàn)從應(yīng)用程序組件中提取常見習(xí)慣用法到自定義 Hooks 中是有非常幫助的。這將使你的組件代碼專注于意圖,并允許你避免頻繁編寫原始 Effects,這也是 React 開發(fā)者所推崇的。

以上就是詳解React自定義Hook的詳細內(nèi)容,更多關(guān)于React自定義Hook的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • react-native DatePicker日期選擇組件的實現(xiàn)代碼

    react-native DatePicker日期選擇組件的實現(xiàn)代碼

    本篇文章主要介紹了react-native DatePicker日期選擇組件的實現(xiàn)代碼,具有一定的參考價值,有興趣的可以了解下
    2017-09-09
  • 嘗試自己動手用react來寫一個分頁組件(小結(jié))

    嘗試自己動手用react來寫一個分頁組件(小結(jié))

    本篇文章主要介紹了嘗試自己動手用react來寫一個分頁組件(小結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • ahooks封裝cookie?localStorage?sessionStorage方法

    ahooks封裝cookie?localStorage?sessionStorage方法

    這篇文章主要為大家介紹了ahooks封裝cookie?localStorage?sessionStorage的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • react-native只保留3x圖原理解析

    react-native只保留3x圖原理解析

    這篇文章主要為大家介紹了react-native只保留3x圖原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • 使用react-virtualized實現(xiàn)圖片動態(tài)高度長列表的問題

    使用react-virtualized實現(xiàn)圖片動態(tài)高度長列表的問題

    一般我們在寫react項目中,同時渲染很多dom節(jié)點,會造成頁面卡頓, 空白的情況。為了解決這個問題,今天小編給大家分享一篇教程關(guān)于react-virtualized實現(xiàn)圖片動態(tài)高度長列表的問題,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • react-router-dom v6版本跳轉(zhuǎn)路徑的實現(xiàn)方法

    react-router-dom v6版本跳轉(zhuǎn)路徑的實現(xiàn)方法

    這篇文章主要介紹了react-router-dom v6版本跳轉(zhuǎn)路徑的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 解決React初始化加載組件會渲染兩次的問題

    解決React初始化加載組件會渲染兩次的問題

    這篇文章主要介紹了解決React初始化加載組件會渲染兩次的問題,文中有出現(xiàn)這種現(xiàn)象的原因及解決方法,感興趣的同學(xué)跟著小編一起來看看吧
    2023-08-08
  • React之使用useState異步刷新的問題

    React之使用useState異步刷新的問題

    這篇文章主要介紹了React之使用useState異步刷新的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • React學(xué)習(xí)筆記之事件處理(二)

    React學(xué)習(xí)筆記之事件處理(二)

    這篇文章主要跟大家介紹了關(guān)于React中事件處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)React具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07
  • 如何用webpack4.0擼單頁/多頁腳手架 (jquery, react, vue, typescript)

    如何用webpack4.0擼單頁/多頁腳手架 (jquery, react, vue, typescript)

    這篇文章主要介紹了如何用webpack4.0擼單頁/多頁腳手架 (jquery, react, vue, typescript),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06

最新評論

仪陇县| 靖远县| 灵石县| 商洛市| 故城县| 定襄县| 赤城县| 离岛区| 赤水市| 绵阳市| 淮北市| 崇礼县| 毕节市| 宁远县| 苏州市| 深水埗区| 东光县| 碌曲县| 利川市| 石楼县| 石阡县| 古田县| 彰化县| 罗山县| 新竹市| 五莲县| 禄劝| 舞阳县| 曲周县| 沂水县| 沙雅县| 泰和县| 剑阁县| 云林县| 绥中县| 花垣县| 尖扎县| 通州区| 湘潭县| 广安市| 铜川市|