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
但是不难发现,其实两个组件的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