eolas/zk/Custom_hook_examples.md

78 lines
1.7 KiB
Markdown
Raw Normal View History

2023-01-23 15:50:08 +00:00
---
tags:
- javascript
- react
- react-hooks
---
# Custom hook examples
## Determine viewport width
### Hook
```js
// useViewportWidth.js
import { useEffect, useState } from "react";
export default function (viewportWidth) {
const [matchesViewportWidth, setMatchesViewportWidth] = useState(false);
useEffect(() => {
const handleResize = () =>
window.innerWidth < viewportWidth
? setMatchesViewportWidth(true)
: setMatchesViewportWidth(false);
window.addEventListener("resize", handleResize);
// Call on initialization to determine initial width
handleResize();
// Clean-up listener to prevent memory leaks
return () => window.removeEventListener("resize", handleResize);
}, [viewportWidth]);
return matchesViewportWidth;
}
```
### Unit test
```js
import useViewportWidth from "./useViewportWidth";
import { fireEvent } from "@testing-library/react";
import { act } from "react-dom/test-utils";
import { renderHook } from "@testing-library/react-hooks";
describe("useViewportWidth", () => {
it("returns `true` when window resized to mobile viewport width", () => {
// Arrange
const { result } = renderHook(() => useViewportWidth(768));
// Act
act(() => {
window.innerWidth = 500;
fireEvent(window, new Event("resize"));
});
// Assert
expect(result.current).toBe(true);
});
it("returns `false` when window resized to width greater than mobile viewport", () => {
// Arrange
const { result } = renderHook(() => useViewportWidth(768));
// Act
act(() => {
window.innerWidth = 1058;
fireEvent(window, new Event("resize"));
});
// Assert
expect(result.current).toBe(false);
});
})``;
```