15 个自定义 Hooks 让你的 React 组件更轻量

2025-05-25

15 个自定义 Hooks 让你的 React 组件更轻量

这里有 15 个自定义钩子,可以让你的 React 组件变得轻量级

React Hooks 是 React 社区的热门词汇。我希望每个 React 开发者都知道什么是 Hooks。简单来说,Hooks 让函数式组件的生命周期方法更加便捷,也鼓励我们编写函数式组件。

让我们深入研究自定义钩子!自定义钩子可以将组件逻辑提取到可复用的函数中,从而提高组件拆分和可靠性。这里我们将介绍 15 个React-use包中的自定义钩子,它们可以使我们的组件更轻量。

1. useIdle

useIdle 钩子用于跟踪页面上的用户是否处于空闲状态。您可以传递两个参数——一个是考虑空闲的时间,另一个是 initialState,用于设置用户初始状态。

import {useIdle} from 'react-use';
const Demo = () => {
  const isIdle = useIdle(3e3);
return (
    <div>
      <div>User is idle: {isIdle ? 'Yes 😴' : 'Nope'}</div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

2. useInterval

此钩子用于与间隔相关的功能。它会clearInterval自动处理组件的卸载。它还允许通过将延迟设置为空来暂停间隔。

import * as React from 'react';
import {useInterval} from 'react-use';
const Demo = () => {
  const [count, setCount] = React.useState(0);
  const [delay, setDelay] = React.useState(1000);
  const [isRunning, toggleIsRunning] = useBoolean(true);
useInterval(
    () => {
      setCount(count + 1);
    },
    isRunning ? delay : null
  );
return (
    <div>
      <div>
        delay: <input value={delay} onChange={event => setDelay(Number(event.target.value))} />
      </div>
      <h1>count: {count}</h1>
      <div>
        <button onClick={toggleIsRunning}>{isRunning ? 'stop' : 'start'}</button>
      </div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

3. 使用Scroll

此钩子用于监听元素的滚动事件,并在滚动时重新渲染。无需手动添加 JavaScript 事件监听器。

import {useScroll} from 'react-use';
const Demo = () => {
  const scrollRef = React.useRef(null);
  const {x, y} = useScroll(scrollRef);
return (
    <div ref={scrollRef}>
      <div>x: {x}</div>
      <div>y: {y}</div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

4. useToggle

此钩子用于在两个状态(例如 TRUE 和 FALSE)之间切换。这种方法减少了手动逻辑。

import {useToggle} from 'react-use';
const Demo = () => {
  const [on, toggle] = useToggle(true);
return (
    <div>
      <div>{on ? 'ON' : 'OFF'}</div>
      <button onClick={toggle}>Toggle</button>
      <button onClick={() => toggle(true)}>set ON</button>
      <button onClick={() => toggle(false)}>set OFF</button>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

5. 使用标题

此钩子用于设置页面标题。

import {useTitle} from 'react-use';
const Demo = () => {
  useTitle('Hello world!');
return null;
};
Enter fullscreen mode Exit fullscreen mode

6. usePrevious

此钩子用于获取先前的状态。我们可能不需要编写自定义逻辑来获取先前的状态。

import {usePrevious} from 'react-use';
const Demo = () => {
  const [count, setCount] = React.useState(0);
  const prevCount = usePrevious(count);
return (
    <p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
      <p>
        Now: {count}, before: {prevCount}
      </p>
    </p>
  );
};
Enter fullscreen mode Exit fullscreen mode

7. useSetState

此钩子用于将对象合并到其当前状态,类似于this.setState类组件中的 。如果您使用多个状态,可以使用useSetState

import {useSetState} from 'react-use';
const Demo = () => {
  const [state, setState] = useSetState({});
return (
    <div>
      <pre>{JSON.stringify(state, null, 2)}</pre>
      <button onClick={() => setState({hello: 'world'})}>hello</button>
      <button onClick={() => setState({foo: 'bar'})}>foo</button>
      <button 
        onClick={() => {
          setState((prevState) => ({
            count: (prevState.count || 0) + 1,
          }))
        }}
      >
        count
      </button>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

8. 使用Cookie

此钩子用于返回 cookie 的当前值、更新 cookie 的回调和删除 cookie 的回调。

import { useCookie } from "react-use";
const Demo = () => {
  const [value, updateCookie, deleteCookie] = useCookie("my-cookie");
  const [counter, setCounter] = useState(1);
useEffect(() => {
    deleteCookie();
  }, []);
const updateCookieHandler = () => {
    updateCookie(`my-awesome-cookie-${counter}`);
    setCounter(c => c + 1);
  };
return (
    <div>
      <p>Value: {value}</p>
      <button onClick={updateCookieHandler}>Update Cookie</button>
      <br />
      <button onClick={deleteCookie}>Delete Cookie</button>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

9. 使用权限

此钩子用于获取浏览器 API 的权限状态。传递 API 名称即可获取权限状态。

import {usePermission} from 'react-use';
const Demo = () => {
  const state = usePermission({ name: 'microphone' });
return (
    <pre>
      {JSON.stringify(state, null, 2)}
    </pre>
  );
};
Enter fullscreen mode Exit fullscreen mode

10. 使用Debounce

此钩子用于延迟事件,直到等待时间结束。在下面的代码中,setState 是在等待时间结束后执行的。

const Demo = () => {
  const [state, setState] = React.useState('Typing stopped');
  const [val, setVal] = React.useState('');
  const [debouncedValue, setDebouncedValue] = React.useState('');
const [, cancel] = useDebounce(
    () => {
      setState('Typing stopped');
      setDebouncedValue(val);
    },
    2000,
    [val]
  );
return (
    <div>
      <input
        type="text"
        value={val}
        placeholder="Debounced input"
        onChange={({ currentTarget }) => {
          setState('Waiting for typing to stop...');
          setVal(currentTarget.value);
        }}
      />
      <div>{state}</div>
      <div>
        Debounced value: {debouncedValue}
        <button onClick={cancel}>Cancel debounce</button>
      </div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

11. 使用地理定位

此钩子用于获取用户地理位置。useGeolocation 返回纬度、经度、海拔和更多信息。

import {useGeolocation} from 'react-use';
const Demo = () => {
  const state = useGeolocation();
return (
    <pre>
      {JSON.stringify(state, null, 2)}
    </pre>
  );
};
Enter fullscreen mode Exit fullscreen mode

12. useNetworkState

此钩子用于获取浏览器的网络状态。useNetworkState 可用于向用户显示连接状态。

import {useNetworkState} from 'react-use';
const Demo = () => {
  const state = useNetworkState();
return (
    <pre>
      {JSON.stringify(state, null, 2)}
    </pre>
  );
};
Enter fullscreen mode Exit fullscreen mode

13. 使用CopyToClipboard

useCopyToClipboard 钩子用于将文本复制到剪贴板。

const Demo = () => {
  const [text, setText] = React.useState('');
  const [state, copyToClipboard] = useCopyToClipboard();

  return (
    <div>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button type="button" onClick={() => copyToClipboard(text)}>copy text</button>
      {state.error
        ? <p>Unable to copy value: {state.error.message}</p>
        : state.value && <p>Copied {state.value}</p>}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

14. 使用Favicon

useFavicon 钩子用于设置页面的图标。

import {useFavicon} from 'react-use';
const Demo = () => {
  useFavicon('https://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico');
return null;
};
Enter fullscreen mode Exit fullscreen mode

15. 使用错误

useError 钩子用于调度错误。

import { useError } from 'react-use';
const Demo = () => {
  const dispatchError = useError();
const clickHandler = () => {
    dispatchError(new Error('Some error!'));
  };
return <button onClick={clickHandler}>Click me to throw</button>;
};
// In parent app
const App = () => (
  <ErrorBoundary>
    <Demo />
  </ErrorBoundary>
);
Enter fullscreen mode Exit fullscreen mode

结论

react-use包中还有一些自定义钩子,希望对你有所帮助。感谢阅读。

想要了解更多?欢迎关注Twitter

你可以给我买杯咖啡来支持我 ☕

电子书

ReactJS 优化技术和开发资源

文章来源:https://dev.to/nilanth/15-custom-hooks-to-make-your-react-component-lightweight-17cd
PREV
5 个软件包可在开发过程中优化和加速您的 React 应用
NEXT
免费托管 React 应用的 10 种方法