自定义hook
// 使用自定义hook来复用代码逻辑
import { useEffect, useState } from "react";
function useWindowSize() {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
<!--truncate-->
useEffect(() => {
const handleResize = () => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
// 浏览器窗口发生变化时,改变windowSize
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
// hook里面返回一个状态、函数或数组
return windowSize;
}
export default useWindowSize;
// --------------------------------------------
import { useEffect, useState } from "react";
import "./App.css";
import useWindowSize from "./hooks/useWindowSize";
function App() {
const windowSize = useWindowSize();
return (
<main className="container">
<div>
<h1>Width: {windowSize.width}</h1>
<h1>Height: {windowSize.height}</h1>
</div>
</main>
);
}
export default App;
给hook添加参数
import { useEffect, useState } from "react";
function useWindowSize(throttleDuration = 100) {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
useEffect(() => {
let timeoutId = null;
const handleResize = () => {
if (!timeoutId) {
timeoutId = setTimeout(() => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
timeoutId = null;
}, throttleDuration);
}
};
window.addEventListener("resize", handleResize);
return () => {
clearInterval(timeoutId);
window.removeEventListener("resize", handleResize);
};
}, [throttleDuration]);
return windowSize;
}
export default useWindowSize;
多个hook联用
import { useState, useEffect } from "react";
const breakpoints = [
{ name: "mobile", width: 480 },
{ name: "tablet", width: 768 },
{ name: "laptop", width: 1024 },
{ name: "desktop", width: 1440 },
];
function useBreakpoint(windowWidth) {
const initialBreakPoint = breakpoints.find(
(breakpoint) => windowWidth <= breakpoint.width
);
const [currentBreakpoint, setCurrentBreakpoint] = useState(
initialBreakPoint?.name || "unknown"
);
useEffect(() => {
for (const breakpoint of breakpoints) {
if (windowWidth <= breakpoint.width) {
setCurrentBreakpoint(breakpoint.name);
break;
}
}
}, [windowWidth]);
return currentBreakpoint;
}
export default useBreakpoint;
import "./App.css";
import ResponsiveContent from "./components/ResponsiveContent";
import useWindowSize from "./hooks/useWindowSize";
import useBreakpoint from "./hooks/useBreakPoint";
function App() {
const windowSize = useWindowSize(500);
const breakpoint = useBreakpoint(windowSize.width);
// breakpoint的值会随着windowSize.width的值改变而改变
// 说明前面hook的返回值会变化,那么后面hook的参数也会跟着变化
return (
<main className="container">
<div>
<h1>Width: {windowSize.width}</h1>
<h1>Height: {windowSize.height}</h1>
<h1>Break Point: {breakpoint}</h1>
</div>
<ResponsiveContent />
</main>
);
}
export default App;