UNPKG

@ehsaneha/react-throttle

Version:

useThrottle is a custom React hook that limits how often a function can be called by ensuring it's invoked at most once within a specified delay period.

55 lines (54 loc) 2.48 kB
import React, { useState } from "react"; import { render, fireEvent, screen, act } from "@testing-library/react"; import { useThrottle } from "./index"; jest.useFakeTimers(); function TestComponent({ delay = 1000 }) { const [value, setValue] = useState(""); const throttledFn = useThrottle((newVal) => { setValue(newVal); }, delay); return (React.createElement("div", null, React.createElement("button", { onClick: () => throttledFn("A") }, "Click A"), React.createElement("button", { onClick: () => throttledFn("B") }, "Click B"), React.createElement("div", { "data-testid": "output" }, value))); } describe("useThrottle (with test component)", () => { it("calls throttled function immediately on first call", () => { render(React.createElement(TestComponent, null)); fireEvent.click(screen.getByText("Click A")); expect(screen.getByTestId("output").textContent).toBe("A"); }); it("throttles multiple rapid calls", () => { render(React.createElement(TestComponent, null)); fireEvent.click(screen.getByText("Click A")); fireEvent.click(screen.getByText("Click B")); // Should be throttled expect(screen.getByTestId("output").textContent).toBe("A"); act(() => { jest.advanceTimersByTime(1000); }); expect(screen.getByTestId("output").textContent).toBe("B"); }); it("does not call throttled function again until delay passes", () => { render(React.createElement(TestComponent, { delay: 500 })); fireEvent.click(screen.getByText("Click A")); act(() => { jest.advanceTimersByTime(300); }); fireEvent.click(screen.getByText("Click B")); // Should still be throttled expect(screen.getByTestId("output").textContent).toBe("A"); act(() => { jest.advanceTimersByTime(300); }); expect(screen.getByTestId("output").textContent).toBe("B"); }); it("cleans up on unmount without calling throttled function again", () => { const { unmount } = render(React.createElement(TestComponent, null)); fireEvent.click(screen.getByText("Click A")); fireEvent.click(screen.getByText("Click B")); unmount(); act(() => { jest.runAllTimers(); }); // Can't assert directly, but this ensures no error is thrown }); });