In-depth understanding of React's custom Hooks
Apr 20, 2023 pm 06:22 PMIn React projects, we often use several built-in Hooks that come with React, such as useState, useContext and useEffect. But sometimes, we may want to have a Hook with a specific purpose: for example, useData to get data, useConnect to get connections, etc. Although these Hooks are not found in React, React provides a very flexible way for you to create your own custom Hooks for your needs.
How to customize Hooks
In React you must follow the following naming convention:
React Component: React component names must be capitalized with Letters starting with , such as StatusBar and SaveButton. React components also need to return something that React knows how to render, such as
JSX
.React Hook: Hook name must start with use, followed by a uppercase letter, such as useState (built-in) or useStatus (custom ). Unlike React components, custom Hooks can return any value.
This naming convention ensures that you can always view the component and understand its status, effectsand other React features that may be "hidden"Location. For example, if you see a getColor() function call in a component, you can be sure that it cannot contain React state because its name does not start with use. However, function calls like useStatus() are likely to contain calls to other Hooks!
Shared logic between components
The code inside them describes what they want to do rather than how to do it .
The core of custom Hooks is the logic between shared components. Using custom Hooks can reduce repetitive logic. More importantly, the code inside custom Hooks describes what they want to do, not how to do it. When you extract logic into custom Hooks, you can hidethe detailsof how to handle calls to certain "external systems" or browser APIs, as the component's code expresses Your intent, not implementation details. The following is a simple example:
import { useState } from 'react'; function useCounter(initialValue) { const [count, setCount] = useState(initialValue); function increment() { setCount(count + 1); } return [count, increment]; }This custom Hook is called
useCounter. It accepts an initial value as a parameter and returns an array containing the current count value and an increment count. function.
Using a custom Hook is very simple, just call it in the function component. Here is an example of using
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> ); }In this example, we imported
useCounter and called it in the component. We destructure the returned array into
count and
increment and use them in the component.
useCounter as an example:
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> ); }When we click
Increment2, it will not affect
count1, because each
The calls to useCounter are all independent, and their internal states are also independent.
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; }useLocalStorageThis hook allows you to store and retrieve values ??from local storage.
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]; }Business HooksuseFetchThis hook allows you to get data from the API.
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 }; }useModalThis hook allows you to manage the state of a modal dialog box.
//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;Transmitting information between multiple HooksSince Hook itself is a function, we can pass information between them. Below we take
useUserInfo as an example to obtain user information:
//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> ... </> ) }We save the user id in the
userId state variable. When the user performs a certain operation
setUserId , since
useState provides us with the latest value of the
userId state variable, we can pass it as a parameter to the custom
useUserInfo Hook :
const [userId,setUserId] = useState('103') const userInfo = useUserInfo(userId)At this time, our
userInfo will be updated as userId changes.
This section describes anexperimental API that has not yet been released in a stable version of React. This section describes an experimental API that is not yet released in a stable version of React.
你可能希望讓組件自定義其行為,而不是完全地將邏輯封裝 Hooks 中,我們可以通過(guò)將 event handlers
作為參數(shù)傳遞給 Hooks,下面是一個(gè)聊天室的例子:useChatRoom
接受一個(gè)服務(wù)端 url 和 roomId,當(dāng)調(diào)用這個(gè) Hook 的時(shí)候,會(huì)進(jìn)行連接,
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)連接成功時(shí),你想將此邏輯移回你的組件:
export default function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); useChatRoom({ roomId: roomId, serverUrl: serverUrl, onReceiveMessage(msg) { showNotification('New message: ' + msg); } }); // ...
要做到這一點(diǎn),改變你的自定義 Hook ,把 onReceiveMessage
作為它的命名選項(xiàng)之一:
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 接受事件處理程序時(shí),你還可以做一個(gè)改進(jìn)。
在 onReceiveMessage
上添加依賴(lài)并不理想,因?yàn)樗鼤?huì)導(dǎo)致每次組件重新渲染時(shí)聊天都重新連接。將此事件處理程序包裝到 EffectEvent
中以將其從依賴(lài)項(xiàng)中移除:
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)在不會(huì)在每次重新渲染聊天室組件時(shí)進(jìn)行重新連接。
開(kāi)源 React Hooks 庫(kù)
- ahooks 一套由阿里巴巴開(kāi)源的 React Hooks 庫(kù),封裝了大量好用的 Hooks。
- react-use 一個(gè)必不可少的 React Hooks 集合。其包含了傳感器、用戶(hù)界面、動(dòng)畫(huà)效果、副作用、生命周期、狀態(tài)這六大類(lèi)的Hooks。
- useHooks 一組易于理解的 React Hook集合。
- react-recipes 一個(gè)包含流行的自定義 Hook 的 React Hooks 實(shí)用程序庫(kù)。
- Rhooks ?一組基本的 React 自定義Hooks。
- react-hanger 一組有用的 hooks,用于特定于某些基本類(lèi)型的狀態(tài)更改輔助函數(shù)。
- Beautiful React Hook 一組漂亮的(希望有用的)React hooks 來(lái)加速你的組件和 hooks 開(kāi)發(fā)。
- Awesome React Hooks 一個(gè)很棒的 React Hooks 資源集合,該集合包含React Hooks教程、視頻、工具,Hooks列表。其中Hooks列表中包含了眾多實(shí)用的自定義Hooks。
- SWR 一個(gè)用于獲取數(shù)據(jù)的 React Hooks 庫(kù)。只需一個(gè)Hook,就可以顯著簡(jiǎn)化項(xiàng)目中的數(shù)據(jù)獲取邏輯。
- React Hook Form 一個(gè)用于表單狀態(tài)管理和驗(yàn)證的 React Hooks (Web + React Native)。
總結(jié)
自定義 Hooks 可以幫助你遷移到更好的開(kāi)發(fā)范式。通過(guò)將一些通用邏輯封裝在自定義 Hooks 中,你可以使組件代碼保持簡(jiǎn)潔并專(zhuān)注于核心意圖,這有助于減少重復(fù)性的代碼,并使你的代碼更易于維護(hù)和更新,從而使你能夠更快速地開(kāi)發(fā)新功能。
對(duì)于 Effect 而言,這樣可以使數(shù)據(jù)在 Effects 中流動(dòng)的過(guò)程變得非常明確。這讓你的組件能夠專(zhuān)注于意圖,而不是 Effects 的具體實(shí)現(xiàn)。當(dāng) React 添加新功能時(shí),你可以刪除那些 Effects 而不影響任何組件。就像設(shè)計(jì)系統(tǒng)一樣,你可能會(huì)發(fā)現(xiàn)從應(yīng)用程序組件中提取常見(jiàn)習(xí)慣用法到自定義 Hooks 中是有非常幫助的。這將使你的組件代碼專(zhuān)注于意圖,并允許你避免頻繁編寫(xiě)原始 Effects,這也是 React 開(kāi)發(fā)者所推崇的。
(Learning video sharing: Basic Programming Video)
The above is the detailed content of In-depth understanding of React's custom Hooks. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

PHP and Vue: a perfect pairing of front-end development tools. In today's era of rapid development of the Internet, front-end development has become increasingly important. As users have higher and higher requirements for the experience of websites and applications, front-end developers need to use more efficient and flexible tools to create responsive and interactive interfaces. As two important technologies in the field of front-end development, PHP and Vue.js can be regarded as perfect tools when paired together. This article will explore the combination of PHP and Vue, as well as detailed code examples to help readers better understand and apply these two

As a fast and efficient programming language, Go language is widely popular in the field of back-end development. However, few people associate Go language with front-end development. In fact, using Go language for front-end development can not only improve efficiency, but also bring new horizons to developers. This article will explore the possibility of using the Go language for front-end development and provide specific code examples to help readers better understand this area. In traditional front-end development, JavaScript, HTML, and CSS are often used to build user interfaces

Django is a web application framework written in Python that emphasizes rapid development and clean methods. Although Django is a web framework, to answer the question whether Django is a front-end or a back-end, you need to have a deep understanding of the concepts of front-end and back-end. The front end refers to the interface that users directly interact with, and the back end refers to server-side programs. They interact with data through the HTTP protocol. When the front-end and back-end are separated, the front-end and back-end programs can be developed independently to implement business logic and interactive effects respectively, and data exchange.

As a C# developer, our development work usually includes front-end and back-end development. As technology develops and the complexity of projects increases, the collaborative development of front-end and back-end has become more and more important and complex. This article will share some front-end and back-end collaborative development techniques to help C# developers complete development work more efficiently. After determining the interface specifications, collaborative development of the front-end and back-end is inseparable from the interaction of API interfaces. To ensure the smooth progress of front-end and back-end collaborative development, the most important thing is to define good interface specifications. Interface specification involves the name of the interface

In front-end development interviews, common questions cover a wide range of topics, including HTML/CSS basics, JavaScript basics, frameworks and libraries, project experience, algorithms and data structures, performance optimization, cross-domain requests, front-end engineering, design patterns, and new technologies and trends. . Interviewer questions are designed to assess the candidate's technical skills, project experience, and understanding of industry trends. Therefore, candidates should be fully prepared in these areas to demonstrate their abilities and expertise.

Methods for implementing instant messaging include WebSocket, Long Polling, Server-Sent Events, WebRTC, etc. Detailed introduction: 1. WebSocket, which can establish a persistent connection between the client and the server to achieve real-time two-way communication. The front end can use the WebSocket API to create a WebSocket connection and achieve instant messaging by sending and receiving messages; 2. Long Polling, a technology that simulates real-time communication, etc.

Django: A magical framework that can handle both front-end and back-end development! Django is an efficient and scalable web application framework. It is able to support multiple web development models, including MVC and MTV, and can easily develop high-quality web applications. Django not only supports back-end development, but can also quickly build front-end interfaces and achieve flexible view display through template language. Django combines front-end development and back-end development into a seamless integration, so developers don’t have to specialize in learning

Combination of Golang and front-end technology: To explore how Golang plays a role in the front-end field, specific code examples are needed. With the rapid development of the Internet and mobile applications, front-end technology has become increasingly important. In this field, Golang, as a powerful back-end programming language, can also play an important role. This article will explore how Golang is combined with front-end technology and demonstrate its potential in the front-end field through specific code examples. The role of Golang in the front-end field is as an efficient, concise and easy-to-learn
