React自定义Hook
2023-02-17 本文已影响0人
YiYa_咿呀
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