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;
点击按钮.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;

但是去控制发现会报错


报错.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的尾声,小单想为自己鼓掌,加油!坚持~


小单真棒.gif
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 本文首发于公众号【一个老码农】 什么是hook Hook是 React 16.8 的新增特性。它通常与函数式组件同...
    剑老师阅读 679评论 0 0
  • 在react类组件中,有组件间可共享逻辑时,一般用高阶组件的方式对公共逻辑进行复用,在react函数组件中,hoo...
    汤姆威廉斯阅读 1,843评论 0 0
  • 什么是自定义hook? 使用自定义hook可以将某些组件逻辑提取到可重用的函数中。 自定义hook是一个从use开...
    魂斗驴阅读 6,823评论 1 3
  • 自定义 Hook 必须以 “use” 开头吗?**必须如此。这个约定非常重要。不遵循的话,由于无法判断某个函数是否...
    怒默阅读 235评论 0 1
  • 前言 哈喽,大家好,我是海怪。 最近把项目里的 utils 以及 components 里的东西都测完了,算是完成...
    写代码的海怪阅读 460评论 0 0

友情链接更多精彩内容