React自定义Hook

简介: React自定义Hook
1.什么是自定义 Hook?

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

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

注意点: 在React中只有两个地方可以使用Hook

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

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>
    )
}
function App() {
    const [show, setShow] = useState(true);
    return (
        <div>
            {show && <Home/>}
            {show && <About/>}
            <button onClick={()=>{setShow(!show)}}>切换</button>
        </div>
    )
}
export default App;

67.png

清空控制台再次点击按钮.png


但是不难发现,其实两个组件的useEffect里头的方法高度相似,容易造成代码冗余,这个时候我们可以将方法抽取出来,尝试一下吧!

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

但是去控制发现会报错


66.png

报错.png


但是为什么会报错呢?

原因是useEffect属于react-hooks,他只能在函数式组件内使用,现在把它定义在外面自然会报错

怎么解决呢?使用自定义的Hooks,通过函数命名来定义,只需将addlistener函数名改为useAddListener即可

function useAddListenr(name) {
    useEffect(()=>{
        console.log(name, ' - 组件被挂载或者更新完成 -- 添加监听');
        return ()=>{
            console.log(name, ' - 组件即将被卸载 -- 移出监听');
        }
    });
}

完整代码[final solution]:

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

注意点二:在企业开发中, 但凡需要抽取代码, 但凡被抽取的代码中用到了其它的Hook, 那么就必须把这些代码抽取到自定义Hook中

import React, {createContext, useContext} from 'react';
const UserContext = createContext({});
const InfoContext = createContext({});
function useGetContext() {
//用到了useContext的hook,因此必须使用自定义hook来抽取代码进行优化
    const user = useContext(UserContext);
    const info = useContext(InfoContext);
    return [user, info]
}
function Home() {
    // const user = useContext(UserContext);
    // const info = useContext(InfoContext);
    const [user, info] = useGetContext();
    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);
    const [user, info] = useGetContext();
    return (
        <div>
            <p>{user.name}</p>
            <p>{user.age}</p>
            <p>{info.gender}</p>
            <hr/>
        </div>
    )
}
function App() {
    return (
        <UserContext.Provider value={{name:'yiya_xiaoshan', age:18}}>
            <InfoContext.Provider value={{gender:'female'}}>
                <Home/>
                <About/>
            </InfoContext.Provider>
        </UserContext.Provider>
    )
}
export default App;

不惧怕困难,走出舒适区真正的成长总是有汗水和艰辛造就的,安逸只会让我们慢慢失去活力

不知不觉已经到了学习react的尾声,小单想为自己鼓掌,加油!坚持~


65.png

小单真棒.gif


目录
相关文章
|
1月前
|
设计模式 存储 前端开发
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
|
3天前
|
前端开发
React给antd中TreeSelect组件左侧加自定义图标icon
本文介绍了如何在React中为Ant Design的TreeSelect组件的每个树节点添加自定义图标,并解决了因缺少key属性而导致的警告问题,展示了如何通过递归函数处理treeData数据并为每个节点添加图标。
13 2
React给antd中TreeSelect组件左侧加自定义图标icon
|
26天前
|
前端开发 Python
React技术栈-React路由插件之自定义组件标签
关于React技术栈中React路由插件自定义组件标签的教程。
42 4
React技术栈-React路由插件之自定义组件标签
|
1月前
|
前端开发 JavaScript
|
28天前
|
前端开发
React 中的 Hook 概念
【8月更文挑战第31天】
22 0
|
2月前
|
前端开发 JavaScript 数据格式
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
61 1
|
2月前
|
前端开发
React useImperativeHandle Hook
【7月更文挑战第1天】React useImperativeHandle Hook
20 3
|
2月前
|
前端开发
Vue3 【仿 react 的 hook】封装 useTitle
Vue3 【仿 react 的 hook】封装 useTitle
29 0
|
2月前
|
前端开发 API
Vue3 【仿 react 的 hook】封装 useLocation
Vue3 【仿 react 的 hook】封装 useLocation
25 0
|
3月前
|
JSON 弹性计算 前端开发
函数计算产品使用问题之遇到在自定义运行时部署React项目时遇到样式无法正常加载。一般是什么导致的
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。