首页 > web前端 > js教程 > React hooks 每个 JavaScript 开发者都必须收藏

React hooks 每个 JavaScript 开发者都必须收藏

Patricia Arquette
发布: 2024-11-03 18:00:05
原创
902 人浏览过

 React hooks every JavaScript developer must bookmark

React 是一个开源 JavaScript 库,用于构建出色且复杂的用户界面,并且是 JavaScript 生态系统中最受欢迎的库之一。

太长了?

React hooks 是允许您在功能组件中使用 React 状态和其他功能的函数,从而无需编写复杂的 React 类即可实现处理副作用和访问上下文等任务。使用 React hooks 还可以增强开发人员的代码可读性和可维护性。

在本文中,我将分享 38 个 React.js 钩子及其用例的列表,这可以被认为是 React 和 JavaScript 开发人员的最佳资源之一。

 React hooks every JavaScript developer must bookmark

1. 使用状态

管理本地组件状态。

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

登录后复制
登录后复制

2.使用效果

在函数组件中执行副作用。

import { useEffect, useState } from 'react';

function DataFetcher() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);

  return <div>Data: {data ? JSON.stringify(data) : 'Loading...'}</div>;
}

登录后复制
登录后复制

3.使用上下文

使用组件中的上下文。

import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button style={{ background: theme.background }}>Click me</button>;
}

登录后复制
登录后复制

4.使用Reducer

管理复杂的状态逻辑

import { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <span>{state.count}</span>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
    </div>
  );
}

登录后复制
登录后复制

5.使用回调

返回记忆的回调函数。

import { useCallback, useState } from 'react';

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

  const increment = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return <button onClick={increment}>Count: {count}</button>;
}

登录后复制
登录后复制

6. 使用备忘录

记忆昂贵的计算,即存储资源密集型计算的结果以供将来使用。

import { useMemo, useState } from 'react';

function Fibonacci() {
  const [num, setNum] = useState(1);

  const fib = useMemo(() => {
    const computeFib = (n) => (n <= 1 ? n : computeFib(n - 1) + computeFib(n - 2));
    return computeFib(num);
  }, [num]);

  return (
    <div>
      <button onClick={() => setNum(num + 1)}>Next Fibonacci</button>
      <p>Fibonacci of {num} is {fib}</p>
    </div>
  );
}

登录后复制
登录后复制

7.useRef

访问 DOM 元素或存储可变值。

import { useRef } from 'react';

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <div>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </div>
  );
}

登录后复制
登录后复制

8.useImperativeHandle

自定义引用公开的实例值。

import { forwardRef, useImperativeHandle, useRef } from 'react';

const FancyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));
  return <input ref={inputRef} />;
});

function App() {
  const fancyInputRef = useRef();
  return (
    <div>
      <FancyInput ref={fancyInputRef} />
      <button onClick={() => fancyInputRef.current.focus()}>Focus input</button>
    </div>
  );
}

登录后复制
登录后复制

9. 使用布局效果

与 DOM 布局同步。

import { useEffect, useLayoutEffect, useRef, useState } from 'react';

function MeasureWidth() {
  const ref = useRef();
  const [width, setWidth] = useState(0);

  useLayoutEffect(() => {
    setWidth(ref.current.offsetWidth);
  }, []);

  return (
    <div>
      <div ref={ref} style={{ width: '50%' }}>
        Resize the window to see the effect.
      </div>
      <p>Width: {width}px</p>
    </div>
  );
}

登录后复制
登录后复制

10.使用调试值

在 React DevTools 中显示自定义标签。

import { useDebugValue, useState } from 'react';

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useDebugValue(isOnline ? 'Online' : 'Offline');

  // Simulate an asynchronous operation
  setTimeout(() => setIsOnline(Math.random() > 0.5), 1000);

  return isOnline;
}

function FriendStatus({ friendID }) {
  const isOnline = useFriendStatus(friendID);

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

登录后复制
登录后复制

11.使用Fetch

从 API 获取数据。

import { useEffect, useState } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        setData(data);
        setLoading(false);
      });
  }, [url]);

  return { data, loading };
}

function App() {
  const { data, loading } = useFetch('https://jsonplaceholder.typicode.com/posts');

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

  return (
    <ul>
      {data.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

登录后复制
登录后复制

12.使用本地存储

使用本地存储管理状态。

import { useState } from 'react';

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(error);
      return initialValue;
    }
  });

  const setValue = (value) => {
    try {
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.error(error);
    }
  };

  return [storedValue, setValue];
}

function App() {
  const [name, setName] = useLocalStorage('name', 'Bob');

  return (
    <div>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <p>Hello, {name}!</p>
    </div>
  );
}

登录后复制
登录后复制

13.使用Debounce

随着时间的推移对值进行去抖。

import { useEffect, useState } from 'react';

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debouncedValue;
}

function App() {
  const [text, setText] = useState('');
  const debouncedText = useDebounce(text, 500);

  return (
    <div>
      <input value={text} onChange={(e) => setText(e.target.value)} />
      <p>Debounced Value: {debouncedText}</p>
    </div>
  );
}

登录后复制
登录后复制

14.使用上一个

存储变量的先前值。

import { useEffect, useRef } from 'react';

function usePrevious(value) {
  const ref = useRef();

  useEffect(() => {
    ref.current = value;
  }, [value]);

  return ref.current;
}

function App() {
  const [count, setCount] = useState(0);
  const previousCount = usePrevious(count);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Count: {count}</button>
      <p>Previous Count: {previousCount}</p>
    </div>
  );
}

登录后复制
登录后复制

15. 使用窗口大小

跟踪窗口大小。

import { useEffect, useState } from 'react';

function useWindowSize() {
  const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });

  useEffect(() => {
    const handleResize = () => {
      setSize({ width: window.innerWidth, height: window.innerHeight });
    };

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return size;
}

function App() {
  const { width, height } = useWindowSize();

  return (
    <div>
      <p>Width: {width}px</p>
      <p>Height: {height}px</p>
    </div>
  );
}

登录后复制
登录后复制

16.使用悬停

检测元素是否悬停。

import { useCallback, useState } from 'react';

function useHover() {
  const [hovered, setHovered] = useState(false);

  const onMouseOver = useCallback(() => setHovered(true), []);
  const onMouseOut = useCallback(() => setHovered(false), []);

  return { hovered, onMouseOver, onMouseOut };
}

function HoverComponent() {
  const { hovered, onMouseOver, onMouseOut } = useHover();

  return (
    <div onMouseOver={onMouseOver} onMouseOut={onMouseOut}>
      {hovered ? 'Hovering' : 'Not Hovering'}
    </div>
  );
}

登录后复制
登录后复制

17. 使用在线状态

跟踪在线状态。

import { useEffect, useState } from 'react';

function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(navigator.onLine);

  useEffect(() => {
    const handleOnline = () => setIsOnline(true);
    const handleOffline = () => setIsOnline(false);

    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);

    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  return isOnline;
}

function App() {
  const isOnline = useOnlineStatus();

  return <div>{isOnline ? 'Online' : 'Offline'}</div>;
}

登录后复制
登录后复制

18. 使用事件监听器

附加事件监听器。

import { useEffect, useRef } from 'react';

function useEventListener(eventName, handler, element = window) {
  const savedHandler = useRef();

  useEffect(() => {
    savedHandler.current = handler;
  }, [handler]);

  useEffect(() => {
    const eventListener = (event) => savedHandler.current(event);
    element.addEventListener(eventName, eventListener);

    return () => {
      element.removeEventListener(eventName, eventListener);
    };
  }, [eventName, element]);
}

function App() {
  useEventListener('click', () => alert('Window clicked!'));

  return <div>Click anywhere!</div>;
}

登录后复制
登录后复制

19.使用间隔

设置具有动态延迟的间隔。

import { useEffect, useRef } from 'react';

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

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

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

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

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

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

登录后复制
登录后复制

20. 使用超时

设置超时。

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

登录后复制
登录后复制

21. 使用OnClickOutside

检测组件外部的点击。

import { useEffect, useState } from 'react';

function DataFetcher() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);

  return <div>Data: {data ? JSON.stringify(data) : 'Loading...'}</div>;
}

登录后复制
登录后复制

22.使用剪贴板

处理剪贴板操作。

import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button style={{ background: theme.background }}>Click me</button>;
}

登录后复制
登录后复制

23.使用深色模式

管理深色模式偏好。

import { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <span>{state.count}</span>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
    </div>
  );
}

登录后复制
登录后复制

24.使用切换

在布尔值之间切换。

import { useCallback, useState } from 'react';

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

  const increment = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return <button onClick={increment}>Count: {count}</button>;
}

登录后复制
登录后复制

25.使用主题

在浅色和深色主题之间切换。

import { useMemo, useState } from 'react';

function Fibonacci() {
  const [num, setNum] = useState(1);

  const fib = useMemo(() => {
    const computeFib = (n) => (n <= 1 ? n : computeFib(n - 1) + computeFib(n - 2));
    return computeFib(num);
  }, [num]);

  return (
    <div>
      <button onClick={() => setNum(num + 1)}>Next Fibonacci</button>
      <p>Fibonacci of {num} is {fib}</p>
    </div>
  );
}

登录后复制
登录后复制

26.使用媒体

查询媒体属性。

import { useRef } from 'react';

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <div>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </div>
  );
}

登录后复制
登录后复制

27. 使用LockBodyScroll

锁定正文卷轴。

import { forwardRef, useImperativeHandle, useRef } from 'react';

const FancyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));
  return <input ref={inputRef} />;
});

function App() {
  const fancyInputRef = useRef();
  return (
    <div>
      <FancyInput ref={fancyInputRef} />
      <button onClick={() => fancyInputRef.current.focus()}>Focus input</button>
    </div>
  );
}

登录后复制
登录后复制

28.使用按键

检测按键。

import { useEffect, useLayoutEffect, useRef, useState } from 'react';

function MeasureWidth() {
  const ref = useRef();
  const [width, setWidth] = useState(0);

  useLayoutEffect(() => {
    setWidth(ref.current.offsetWidth);
  }, []);

  return (
    <div>
      <div ref={ref} style={{ width: '50%' }}>
        Resize the window to see the effect.
      </div>
      <p>Width: {width}px</p>
    </div>
  );
}

登录后复制
登录后复制

29. 使用文档标题

更新文档标题。

import { useDebugValue, useState } from 'react';

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useDebugValue(isOnline ? 'Online' : 'Offline');

  // Simulate an asynchronous operation
  setTimeout(() => setIsOnline(Math.random() > 0.5), 1000);

  return isOnline;
}

function FriendStatus({ friendID }) {
  const isOnline = useFriendStatus(friendID);

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

登录后复制
登录后复制

30.使用悬停

处理悬停状态。

import { useEffect, useState } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        setData(data);
        setLoading(false);
      });
  }, [url]);

  return { data, loading };
}

function App() {
  const { data, loading } = useFetch('https://jsonplaceholder.typicode.com/posts');

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

  return (
    <ul>
      {data.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

登录后复制
登录后复制

31.使用地理位置

检索地理位置。

import { useState } from 'react';

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(error);
      return initialValue;
    }
  });

  const setValue = (value) => {
    try {
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.error(error);
    }
  };

  return [storedValue, setValue];
}

function App() {
  const [name, setName] = useLocalStorage('name', 'Bob');

  return (
    <div>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <p>Hello, {name}!</p>
    </div>
  );
}

登录后复制
登录后复制

32.使用滚动位置

跟踪滚动位置。

import { useEffect, useState } from 'react';

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debouncedValue;
}

function App() {
  const [text, setText] = useState('');
  const debouncedText = useDebounce(text, 500);

  return (
    <div>
      <input value={text} onChange={(e) => setText(e.target.value)} />
      <p>Debounced Value: {debouncedText}</p>
    </div>
  );
}

登录后复制
登录后复制

33. 使用卸载

在组件卸载时运行函数。

import { useEffect, useRef } from 'react';

function usePrevious(value) {
  const ref = useRef();

  useEffect(() => {
    ref.current = value;
  }, [value]);

  return ref.current;
}

function App() {
  const [count, setCount] = useState(0);
  const previousCount = usePrevious(count);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Count: {count}</button>
      <p>Previous Count: {previousCount}</p>
    </div>
  );
}

登录后复制
登录后复制

34.使用ClickOutside

检测元素外部的点击。

import { useEffect, useState } from 'react';

function useWindowSize() {
  const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });

  useEffect(() => {
    const handleResize = () => {
      setSize({ width: window.innerWidth, height: window.innerHeight });
    };

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return size;
}

function App() {
  const { width, height } = useWindowSize();

  return (
    <div>
      <p>Width: {width}px</p>
      <p>Height: {height}px</p>
    </div>
  );
}

登录后复制
登录后复制

35. 使用DebouncedCallback

对回调函数进行去抖动。

import { useCallback, useState } from 'react';

function useHover() {
  const [hovered, setHovered] = useState(false);

  const onMouseOver = useCallback(() => setHovered(true), []);
  const onMouseOut = useCallback(() => setHovered(false), []);

  return { hovered, onMouseOver, onMouseOut };
}

function HoverComponent() {
  const { hovered, onMouseOver, onMouseOut } = useHover();

  return (
    <div onMouseOver={onMouseOver} onMouseOut={onMouseOut}>
      {hovered ? 'Hovering' : 'Not Hovering'}
    </div>
  );
}

登录后复制
登录后复制

36.使用节流阀

随着时间的推移限制值。

import { useEffect, useState } from 'react';

function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(navigator.onLine);

  useEffect(() => {
    const handleOnline = () => setIsOnline(true);
    const handleOffline = () => setIsOnline(false);

    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);

    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  return isOnline;
}

function App() {
  const isOnline = useOnlineStatus();

  return <div>{isOnline ? 'Online' : 'Offline'}</div>;
}

登录后复制
登录后复制

37. 使用更新效果

仅在更新时运行效果,而不是在安装时运行效果。

import { useEffect, useRef } from 'react';

function useEventListener(eventName, handler, element = window) {
  const savedHandler = useRef();

  useEffect(() => {
    savedHandler.current = handler;
  }, [handler]);

  useEffect(() => {
    const eventListener = (event) => savedHandler.current(event);
    element.addEventListener(eventName, eventListener);

    return () => {
      element.removeEventListener(eventName, eventListener);
    };
  }, [eventName, element]);
}

function App() {
  useEventListener('click', () => alert('Window clicked!'));

  return <div>Click anywhere!</div>;
}

登录后复制
登录后复制

38.使用本地存储

管理本地存储中的状态

import { useEffect, useRef } from 'react';

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

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

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

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

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

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

登录后复制
登录后复制

React.js 易于学习和掌握,拥有大量免费课程和资源,以及庞大且活跃的开发者社区
确保在你的下一个项目中使用这些 React hooks,并关注我以获取更多这样的内容

 React hooks every JavaScript developer must bookmark

Kumar Kalyan

技术内容编辑和作家

GIF 信用

如果您喜欢该动图,请务必在 Instagram 上关注经理 Jeremy

以上是React hooks 每个 JavaScript 开发者都必须收藏的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板