常用的自定义hooks

293 阅读3分钟

当我们在开发React应用程序时,我们通常会编写许多重复的代码。例如,当我们需要在组件之间共享状态时,我们通常需要使用React的状态提升或Redux等库来解决。然而,自定义Hooks可以帮助我们更好地组织和重用我们的代码。在本文中,我们将介绍5个常见的React自定义Hooks,帮助您更好地管理和复用代码。

1. useInput

使用useInput hook可以轻松地处理表单输入。此自定义hook接受一个默认值,然后返回一个包含当前值和一个更新值的函数的数组。

import { useState } from 'react';

function useInput(initialValue) {
  const [value, setValue] = useState(initialValue);
  const handleChange = (event) => {
    setValue(event.target.value);
  };
  return [value, handleChange];
}

这使我们可以在表单输入中使用它:

function MyForm() {
  const [username, setUsername] = useInput('');
  const [password, setPassword] = useInput('');
  
  const handleSubmit = (event) => {
    event.preventDefault();
    console.log(`Username: ${username}, Password: ${password}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" value={username} onChange={setUsername} />
      <input type="password" value={password} onChange={setPassword} />
      <button type="submit">Submit</button>
    </form>
  );
}

2. useToggle

使用useToggle hook可以在布尔值之间轻松切换状态。此自定义hook接受一个初始值,并返回一个布尔值和一个切换状态的函数。

import { useState } from 'react';

function useToggle(initialValue) {
  const [value, setValue] = useState(initialValue);
  const toggleValue = () => {
    setValue(!value);
  };
  return [value, toggleValue];
}

我们可以将其用于开关:

function MySwitch() {
  const [isOn, toggleIsOn] = useToggle(false);
  
  return (
    <>
      <p>The switch is {isOn ? 'on' : 'off'}</p>
      <button onClick={toggleIsOn}>Toggle</button>
    </>
  );
}

3. useLocalStorage

使用useLocalStorage hook可以轻松地将状态存储在本地存储中。此自定义hook接受一个键和一个初始值,并返回一个包含当前值和一个更新值的函数的数组。它还会将当前值保存到本地存储中,并在重新渲染时从本地存储中恢复值。

import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const item = window.localStorage.getItem(key);
    return item ? JSON.parse(item) : initialValue;
  });

  useEffect(() => {
    window.localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
}

我们可以在组件中使用它:

function MyComponent() {
  const [count, setCount] = useLocalStorage('count', 0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

4. useMediaQuery

使用useMediaQuery hook可以根据媒体查询的状态更改应用程序的样式或行为。此自定义hook接受一个媒体查询字符串,并返回一个布尔值,指示查询是否匹配。

import { useState, useEffect } from 'react';

function useMediaQuery(query) {
  const [matches, setMatches] = useState(false);
  
  useEffect(() => {
    const media = window.matchMedia(query);
    if (media.matches !== matches) {
      setMatches(media.matches);
    }
    const listener = () => {
      setMatches(media.matches);
    };
    media.addListener(listener);
    return () => media.removeListener(listener);
  }, [matches, query]);
  
  return matches;
}

我们可以将其用于根据屏幕大小调整应用程序的布局:

function MyComponent() {
  const isSmallScreen = useMediaQuery('(max-width: 640px)');
  
  return (
    <div>
      {isSmallScreen ? (
        <p>Small Screen</p>
      ) : (
        <p>Large Screen</p>
      )}
    </div>
  );
}

5. useInterval

使用useInterval hook可以轻松地创建一个可暂停的定时器。此自定义hook接受一个回调函数和一个间隔时间,并在指定的时间间隔后调用回调函数。

import { useEffect, useRef } from 'react';

function useInterval(callback, delay) {
  const savedCallback = useRef();

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

  useEffect(() => {
    const tick = () => savedCallback.current();
    if (delay !== null) {
      const intervalId = setInterval(tick, delay);
      return () => clearInterval(intervalId);
    }
  }, [delay]);
}

我们可以将其用于在应用程序中定期更新状态:

function MyComponent() {
  const [count, setCount] = useState(0);

  useInterval(() => {
    setCount(count + 1);
  }, 1000);

  return <div>{count}</div>;
}

这是5个常见的React自定义Hooks。使用自定义Hooks可以帮助您更好地组织和重用代码,并使您的应用程序更易于维护。