最适合你的 React 项目的 Hooks

2025-06-04

最适合你的 React 项目的 Hooks

React.js 目前是前端开发人员最流行的 JavaScript 库之一。

React 确实改变了我们构建单页应用程序 (SPA) 的方式。它最强大的功能之一是 React 16.8 中引入的 hooks,这个新功能让我们能够使用函数式组件来处理状态,而无需使用类组件。

React 提供了一些自定义 hooks 的实现方式。一些很棒的自定义 hooks 如下:

useTimeout 钩子

通过这个自定义钩子,我们可以使用声明式方法实现 javascript setTimeout。

代码

import { useEffect, useRef } from 'react';

const useTimeout = (callback, timeout) => {
  const savedCallback = useRef(null);
  savedCallback.current = callback;

  useEffect(
    () => {
      savedCallback.current = callback;
    },
    [callback]
  );

  useEffect(
    () => {
      if (timeout) {
        const timeoutId = setTimeout(() => {
          savedCallback.current();
        }, timeout);
        return () => clearTimeout(timeoutId)
      }
    },
    [timeout]
  )
}
Enter fullscreen mode Exit fullscreen mode

使用示例

import { useState } from 'react';

const ExampleComponent = () => {
  const [message, setMessage] = useState('');
  useTimeout(() => {
    setMessage('Hello World');
  }, 7500);

  return (<p>{message}</p>);
}
Enter fullscreen mode Exit fullscreen mode

编辑 useTimeout

usePrevious 钩子

通过这个自定义钩子,我们可以访问与组件相关的先前状态。

代码

import { useEffect, useRef } from 'react';

const usePrevious = (state) =>  {
  const ref = useRef();

  useEffect(() => {
    ref.current = state;
  });

  return ref.current;
}
Enter fullscreen mode Exit fullscreen mode

使用示例

import { useState } from 'react';

const ExampleComponent = () => {
  const [counter, setCounter] = useState(0);
  const previousCounter = usePrevious(counter);

  return (
    <>
      <p>Counter: {counter}</p>
      <p>Previous Counter: {previousCounter}</p>
      <button onClick={() => setCounter(counter + 1)}>Next</button>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

编辑使用上一个

useInterval 钩子

通过这个自定义钩子,我们可以使用声明式方法实现 javascript setInterval。

代码

import { useEffect, useRef } from 'react';

const useInterval = (callback, delay) => {
  const savedCallback = useRef(null);
  savedCallback.current = callback;

  useEffect(
    () => {
      savedCallback.current = callback;
    },
    [callback]
  );

  useEffect(
    () => {
      if (delay) {
        const intervalId = setInterval(() => {
          savedCallback.current();
        }, delay);
        return () => clearInterval(intervalId)
      }
    },
    [delay]
  )
}
Enter fullscreen mode Exit fullscreen mode

使用示例

import { useState } from 'react';

const ExampleComponent = () => {
  const [seconds, setSeconds] = useState(0);
  useInterval(() => {
    setSeconds(seconds + 1);
  }, 1000);

  return <p> Seconds passed: {seconds}</p>;
}
Enter fullscreen mode Exit fullscreen mode

编辑 useInterval

useFetch 钩子

useFetch 钩子可以用来以声明式的方式实现获取操作。此外,这个自定义钩子还有助于处理加载和错误等行为。

代码

import { useState, useEffect } from 'react';

const useFetch = (initialUrl, initialOptions = {}) => {
  const [url, setUrl] = useState(initialUrl);
  const [options, setOptions] = useState(initialOptions);
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const fetchData = async() => {
      try {
        setIsLoading(true);
        const response = await fetch(url, options);
        const json = await response.json();
        setData(json);
      } catch (err) {
        setError(err);
      } finally {
        setIsLoading(false);
      }
    }
    fetchData();
  }, [url, options]);

  return ({data, error, isLoading, setUrl, setOptions});
};
Enter fullscreen mode Exit fullscreen mode

使用示例

const URL = 'https://jsonplaceholder.typicode.com/todos';

const ExampleComponent = () {
  const { data, error, isLoading } = useFetch(URL);

  if(isLoading) {
    return (<p>Loading...</p>)
  }

  if (error) {
    return <p>{error?.message}</p>;
  }

  const renderItem = ({id, title})=> (
    <div key = {`item-${id}`}>
      <p>{id} - {title}</p>
    </div>
  );

  return data.map(renderItem);
}
Enter fullscreen mode Exit fullscreen mode

编辑 useFetch

useConstructor 钩子

useContructor 钩子可用于实现与类组件相同的行为。

代码

import React from 'react';

export const useConstructor = (callBack = () => {}) => {
  const [hasBeenCalled, setHasBeenCalled] = React.useState(false);
  if (hasBeenCalled) return;
  callBack();
  setHasBeenCalled(true);
};


Enter fullscreen mode Exit fullscreen mode

我将用新的精彩钩子更新帖子

文章来源:https://dev.to/brayanarrieta/most-awesome-hooks-for-your-react-project-4dcp
PREV
我的 NextJS tailwindcss 作品集完成了!!💎
NEXT
使用 Angular Router 原生设置页面标题🔥