In-depth understanding of React's custom Hooks
In 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]; }
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> ); }
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> ); }
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; }
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]; }
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 }; }
//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;
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> ... </> ) }
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)
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 中,我们可以通过将 event handlers
作为参数传递给 Hooks,下面是一个聊天室的例子:useChatRoom
接受一个服务端 url 和 roomId,当调用这个 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]); }
假设当连接成功时,你想将此逻辑移回你的组件:
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 }
这可以工作,但是当你的自定义 Hook 接受事件处理程序时,你还可以做一个改进。
在 onReceiveMessage
上添加依赖并不理想,因为它会导致每次组件重新渲染时聊天都重新连接。将此事件处理程序包装到 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 }
现在不会在每次重新渲染聊天室组件时进行重新连接。
开源 React Hooks 库
- ahooks 一套由阿里巴巴开源的 React Hooks 库,封装了大量好用的 Hooks。
- react-use 一个必不可少的 React Hooks 集合。其包含了传感器、用户界面、动画效果、副作用、生命周期、状态这六大类的Hooks。
- useHooks 一组易于理解的 React Hook集合。
- react-recipes 一个包含流行的自定义 Hook 的 React Hooks 实用程序库。
- Rhooks 一组基本的 React 自定义Hooks。
- react-hanger 一组有用的 hooks,用于特定于某些基本类型的状态更改辅助函数。
- Beautiful React Hook 一组漂亮的(希望有用的)React hooks 来加速你的组件和 hooks 开发。
- Awesome React Hooks 一个很棒的 React Hooks 资源集合,该集合包含React Hooks教程、视频、工具,Hooks列表。其中Hooks列表中包含了众多实用的自定义Hooks。
- SWR 一个用于获取数据的 React Hooks 库。只需一个Hook,就可以显着简化项目中的数据获取逻辑。
- React Hook Form 一个用于表单状态管理和验证的 React Hooks (Web + React Native)。
总结
自定义 Hooks 可以帮助你迁移到更好的开发范式。通过将一些通用逻辑封装在自定义 Hooks 中,你可以使组件代码保持简洁并专注于核心意图,这有助于减少重复性的代码,并使你的代码更易于维护和更新,从而使你能够更快速地开发新功能。
对于 Effect 而言,这样可以使数据在 Effects 中流动的过程变得非常明确。这让你的组件能够专注于意图,而不是 Effects 的具体实现。当 React 添加新功能时,你可以删除那些 Effects 而不影响任何组件。就像设计系统一样,你可能会发现从应用程序组件中提取常见习惯用法到自定义 Hooks 中是有非常帮助的。这将使你的组件代码专注于意图,并允许你避免频繁编写原始 Effects,这也是 React 开发者所推崇的。
(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

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

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

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

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

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.

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

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

How to write and maintain code documentation in Java development In the Java development process, writing and maintaining code documentation is a very important part. A good code document can improve the readability and maintainability of the code, facilitate collaboration and communication between project members, and also help with later code maintenance and iteration. Use of comments Comments are the basis of code documentation. They can be used to explain the function of the code, implementation logic, parameter description, etc. In Java, there are three types of comments: single-line comments (//) and multi-line comments (/.

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.

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
