React

React自定义Hook

2023-02-17  本文已影响0人  YiYa_咿呀
1.什么是自定义 Hook?

通过自定义 Hook,可以对其它Hook的代码进行复用
官方文档地址: https://react.docschina.org/docs/hooks-custom.html

注意点: 在React中只有两个地方可以使用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
上一篇 下一篇

猜你喜欢

热点阅读