React-Hooks-自定义Hook

简介: React-Hooks-自定义Hook

自定义 Hook 概述


  • 通过自定义 Hook,可以对其它 Hook 的代码进行复用

官方文档地址:https://react.docschina.org/docs/hooks-custom.html

假如现在博主有这么一个需求,就是定义两个组件然后在 App 根组件当中进行使用,使用的时候分别为定义的两个组件添加监听, 移除监听:

import React, {useEffect, useState} from 'react';
function Home() {
    useEffect(() => {
        console.log('Home - 组件被挂载或者更新完成 -- 添加监听');
        return () => {
            console.log('Home - 组件即将被卸载 -- 移除监听');
        }
    });
    return (
        <div>Home</div>
    )
}
function About() {
    useEffect(() => {
        console.log('About - 组件被挂载或者更新完成 -- 添加监听');
        return () => {
            console.log('About - 组件即将被卸载 -- 移除监听');
        }
    });
    return (
        <div>About</div>
    )
}
export default function App() {
    const [show, setShow] = useState(true);
    return (
        <div>
            {show && <Home/>}
            {show && <About/>}
            <button onClick={() => {
                setShow(!show)
            }}>切换
            </button>
        </div>
    )
}


测试方式就是运行项目,之后,点击切换按钮即可测试,经过如上的代码可以发现出现了冗余的代码,那么就是存在问题的,那么我们是不是就可以将这些冗余的代码进行抽取一下,抽取之后的代码如下:

import React, {useEffect, useState} from 'react';
function addListener(name) {
    useEffect(() => {
        console.log(name, ' - 组件被挂载或者更新完成 -- 添加监听');
        return () => {
            console.log(name, ' - 组件即将被卸载 -- 移除监听');
        }
    });
}
function Home() {
    addListener('Home');
    return (
        <div>Home</div>
    )
}
function About() {
    addListener('About');
    return (
        <div>About</div>
    )
}
export default function App() {
    const [show, setShow] = useState(true);
    return (
        <div>
            {show && <Home/>}
            {show && <About/>}
            <button onClick={() => {
                setShow(!show)
            }}>切换
            </button>
        </div>
    )
}

抽取之后发现运行报错了,这里就需要回顾一下之前的知识点了,也就是 Hook 的注意点,在 React 中只有两个地方可以使用 Hook:


  • 函数式组件中
  • 自定义 Hook 中




自定义一个 Hooks


只要在函数名称前面加上 use, 那么就表示这个函数是一个自定义 Hook, 就表示可以在这个函数中使用其它的 Hook

好了了解了这些知识点之后,我们接下来就可以解决我们如上示例的报错了,更改代码如下:

import React, {useEffect, useState} from 'react';
function useAddListener(name) {
    useEffect(() => {
        console.log(name, ' - 组件被挂载或者更新完成 -- 添加监听');
        return () => {
            console.log(name, ' - 组件即将被卸载 -- 移除监听');
        }
    });
}
function Home() {
    useAddListener('Home');
    return (
        <div>Home</div>
    )
}
function About() {
    useAddListener('About');
    return (
        <div>About</div>
    )
}
export default function App() {
    const [show, setShow] = useState(true);
    return (
        <div>
            {show && <Home/>}
            {show && <About/>}
            <button onClick={() => {
                setShow(!show)
            }}>切换
            </button>
        </div>
    )
}


如上就是关于自定义 Hook 的内容,到这里我相信如果你跟着的是博主的文档一直看到这里,应该目前是还对自定义 Hook 的印象是不太深的,因为如上的示例我们只是简简单单的打印了文字,不够贴近我们的实际开发,所以博主这里在进行编写一个贴近实际开发的真实案例来巩固一下:

import React, {createContext, useContext} from 'react';
const UserContext = createContext({});
const InfoContext = createContext({});
function Home() {
    const user = useContext(UserContext);
    const info = useContext(InfoContext);
    return (
        <div>
            <p>{user.name}</p>
            <p>{user.age}</p>
            <p>{info.gender}</p>
            <hr/>
        </div>
    )
}
function About() {
    const user = useContext(UserContext);
    const info = useContext(InfoContext);
    return (
        <div>
            <p>{user.name}</p>
            <p>{user.age}</p>
            <p>{info.gender}</p>
            <hr/>
        </div>
    )
}
export default function App() {
    return (
        <UserContext.Provider
            value={{name: 'yangbuyiya', age: 18}}
        >
            <InfoContext.Provider
                value={{gender: 'man'}}
            >
                <Home/>
                <About/>
            </InfoContext.Provider>
        </UserContext.Provider>
    )
}


如上的示例大致就是,通过生产者生产了两个共享变量,然后在其它两个组件当中进行使用都是从 context 当中进行获取数据,这部分的数据其实都是差不多一样的,在企业开发中, 但凡需要抽取代码, 但凡被抽取的代码中用到了其它的 Hook, 那么就必须把这些代码抽取到自定义 Hook 中。

import React, {createContext, useContext} from 'react';
const UserContext = createContext({});
const InfoContext = createContext({});
function useGetContext() {
    const user = useContext(UserContext);
    const info = useContext(InfoContext);
    return [user, info]
}
function Home() {
    const [user, info] = useGetContext();
    return (
        <div>
            <p>{user.name}</p>
            <p>{user.age}</p>
            <p>{info.gender}</p>
            <hr/>
        </div>
    )
}
function About() {
    const [user, info] = useGetContext();
    return (
        <div>
            <p>{user.name}</p>
            <p>{user.age}</p>
            <p>{info.gender}</p>
            <hr/>
        </div>
    )
}
export default function App() {
    return (
        <UserContext.Provider
            value={{name: 'yangbuyiya', age: 18}}
        >
            <InfoContext.Provider
                value={{gender: 'man'}}
            >
                <Home/>
                <About/>
            </InfoContext.Provider>
        </UserContext.Provider>
    )
}

到此为止,自定义 Hook 的实际使用,与巩固已经完结了,看到这里,后面更多的内容就需要自行探究了,React 这一系列的内容就大致写到这。




最后


本期结束咱们下次再见👋~

🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗

相关文章
|
11月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
760 2
|
6月前
|
编解码 前端开发 开发者
React 图片组件样式自定义:常见问题与解决方案
在 React 开发中,图片组件的样式自定义常因细节问题导致布局错乱、性能损耗或交互异常。本文系统梳理常见问题及解决方案,涵盖基础样式应用、响应式设计、加载状态与性能优化等,结合代码案例帮助开发者高效实现图片组件的样式控制。重点解决图片尺寸不匹配、边框阴影不一致、移动端显示模糊、加载失败处理及懒加载等问题,并总结易错点和最佳实践,助力开发者提升开发效率和用户体验。
193 22
|
6月前
|
Web App开发 移动开发 前端开发
React 视频播放器样式自定义实战指南
本文详细介绍了如何在React项目中实现视频播放器的样式自定义,涵盖HTML5 `&lt;video&gt;`标签的基础知识、CSS样式定制技巧及常见问题解决方案。针对全屏模式样式失效、移动端触摸事件冲突和进度条样式定制等问题提供了具体代码示例。同时,探讨了视频预加载策略和内存优化方法,并推荐了几款调试工具,帮助开发者提升用户体验和应用性能。
184 6
|
6月前
|
Web App开发 移动开发 前端开发
React音频播放器样式自定义全解析:从入门到避坑指南
在React中使用HTML5原生&lt;audio&gt;标签时,开发者常面临视觉一致性缺失、样式定制局限和交互体验割裂等问题。通过隐藏原生控件并构建自定义UI层,可以实现完全可控的播放器视觉风格,避免状态不同步等典型问题。结合事件监听、进度条拖拽、浏览器兼容性处理及性能优化技巧,可构建高性能、可维护的音频组件,满足跨平台需求。建议优先使用成熟音频库(如react-player),仅在深度定制需求时采用原生方案。
213 12
|
设计模式 存储 前端开发
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
|
12月前
|
前端开发
React给antd中TreeSelect组件左侧加自定义图标icon
本文介绍了如何在React中为Ant Design的TreeSelect组件的每个树节点添加自定义图标,并解决了因缺少key属性而导致的警告问题,展示了如何通过递归函数处理treeData数据并为每个节点添加图标。
610 2
React给antd中TreeSelect组件左侧加自定义图标icon
|
前端开发 Python
React技术栈-React路由插件之自定义组件标签
关于React技术栈中React路由插件自定义组件标签的教程。
164 4
React技术栈-React路由插件之自定义组件标签
|
11月前
|
前端开发 JavaScript API
自定义React Hooks综合指南
本文介绍了React Hooks及其在组件开发中的作用,重点讲解了自定义Hook的创建和使用方法。通过实例展示了如何创建`useWindowWidth`、`useFetch`和`useForm`等自定义Hook,并分享了使用自定义Hook的最佳实践。文章强调了自定义Hook在提高代码复用性和组件可维护性方面的重要性。
236 0
|
前端开发 JavaScript
|
前端开发
React 中的 Hook 概念
【8月更文挑战第31天】
197 0