usePrevious

记录之前的值。

  1. import { useEffect, useRef } from "react"
  2. function usePrevious<T>(value: T) {
  3. const ref = useRef<T>()
  4. useEffect(() => {
  5. ref.current = value
  6. }, [value])
  7. return ref.current
  8. }

useOnClickOutside

点击元素外,隐藏元素。

  1. type PossibleEvent = {
  2. [Type in HandledEventsType]: HTMLElementEventMap[Type]
  3. }[HandledEventsType]
  4. type Handler = (event: PossibleEvent) => void
  5. function useOnClickOutside(
  6. ref: React.RefObject<HTMLElement>,
  7. handler: Handler) {
  8. useEffect(
  9. () => {
  10. const listener = (event) => {
  11. if (!ref.current || ref.current.contains(event.target)) {
  12. return
  13. }
  14. handler(event)
  15. }
  16. document.addEventListener("mousedown", listener)
  17. document.addEventListener("touchstart", listener)
  18. return () => {
  19. document.removeEventListener("mousedown", listener)
  20. document.removeEventListener("touchstart", listener)
  21. };
  22. },
  23. [ref, handler]
  24. )
  25. }

完善版: use-onclickoutside

useWindowSize

  1. import { useState, useEffect } from "react"
  2. interface Size {
  3. width: number | undefined;
  4. height: number | undefined;
  5. }
  6. function useWindowSize(): Size {
  7. // Initialize state with undefined width/height so server and client renders match
  8. // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
  9. const [windowSize, setWindowSize] = useState<Size>({
  10. width: undefined,
  11. height: undefined,
  12. })
  13. useEffect(() => {
  14. function handleResize() {
  15. setWindowSize({
  16. width: window.innerWidth,
  17. height: window.innerHeight,
  18. })
  19. }
  20. window.addEventListener("resize", handleResize);
  21. handleResize()
  22. return () => window.removeEventListener("resize", handleResize)
  23. }, [])
  24. return windowSize;
  25. }