React 基础巩固(四十六)——自定义Hook的应用
一、自定义Hook的应用
自定义Hook本质上只是一种函数代码逻辑的抽取,严格意义上而言,它并不算React的特性。
-
实现组件创建/销毁时打印日志
import React, { memo, useEffect, useState } from "react"; function useLogLife(name) { useEffect(() => { console.log(`${name}组件创建`); return () => { console.log(`${name}组件销毁`); }; }, []); } const Home = memo(() => { useLogLife("Home"); return <h1>Home Page</h1>; }); const About = memo(() => { useLogLife("About"); return <h1>About Page</h1>; }); export default memo(function App() { const [isShow, setIsShow] = useState(true); useLogLife("App"); return ( <div> <h1>App Component</h1> <button onClick={(e) => setIsShow(!isShow)}>切换</button> {isShow && <Home />} {isShow && <About />} </div> ); });
-
实现Context共享
封装
TokenContext
和UserContext
两个Context在自定义HookuseUserToken
中,通过使用userUserToken
同时获取两个Context的内容:import React, { memo, useContext } from "react"; import { useUserToken } from "./hooks"; const Home = memo(() => { const [user, token] = useUserToken(); console.log(user, token); return <h1>Home Page</h1>; }); const About = memo(() => { const [user, token] = useUserToken(); console.log(user, token); return <h1>About Page</h1>; }); export default memo(function App() { return ( <div> <h1>App Component</h1> <Home /> <About /> </div> ); });
-
实现获取滚动位置
封装滚动监听事件:
import { useEffect, useState } from "react"; function useScrollPosition() { const [scrollX, setScrollX] = useState(0); const [scrollY, setScrollY] = useState(0); useEffect(() => { function handleScroll() { console.log(window.scrollX, window.scrollY); setScrollX(window.scrollX); setScrollY(window.scrollY); } window.addEventListener("scroll", handleScroll); return () => { window.removeEventListener("scroll", handleScroll); }; }, []); return [scrollX, scrollY]; } export default useScrollPosition;
通过
useScrollPosition
自定义Hook进行复用:import React, { memo } from "react"; import "./style.css"; import { useScrollPosition } from "./hooks"; const Home = memo(() => { const [scrollX, scrollY] = useScrollPosition(); console.log("Home", scrollX, scrollY); return ( <h1> Home Page: {scrollX} --- {scrollY} </h1> ); }); const About = memo(() => { const [scrollX, scrollY] = useScrollPosition(); console.log("About", scrollX, scrollY); return ( <h1> About Page: {scrollX} --- {scrollY} </h1> ); }); export default memo(function App() { return ( <div className="app"> <h1>App Component</h1> <Home /> <About /> </div> ); });
-
localStorage数据存储
封装
useLocalStorage
自定义Hook:import { useEffect, useState } from "react"; function useLocalStorage(key) { const [data, setData] = useState(() => { const item = localStorage.getItem(key); if (!item) return ""; return JSON.parse(item); }); useEffect(() => { localStorage.setItem(key, JSON.stringify(data)); }, [data]); return [data, setData]; } export default useLocalStorage;
通过
useLocalStorage
来实现localStorage数据的自动化存储,并进行复用。即,一旦需要本地存储的值发生变化,便对localStorage进行对应的更新:import React, { memo, useEffect, useState } from "react"; import "./style.css"; import { useLocalStorage } from "./hooks"; export default memo(function App() { // 通过key,直接从localStorage获取数据 const [token, setToken] = useLocalStorage("token"); function setTokenHandle() { setToken("new token"); } const [avatarUrl, setAvatarUrl] = useLocalStorage("avatarUrl"); function setAvatarUrlHandle() { setAvatarUrl("new url"); } return ( <div className="app"> <h1>App Component</h1> <h1>token:{token}</h1> <button onClick={setTokenHandle}>设置token</button> <h1>Avatar:{avatarUrl}</h1> <button onClick={setAvatarUrlHandle}>设置avatarUrl</button> </div> ); });