尽可能地列举Hooks及其作用、用法

作用

  1. useState:用于在函数组件中引入状态,返回一个状态变量和一个更新状态的函数
  2. useEffect:用于在函数组件中执行副作用,接受一个函数作为参数,该函数会在组件渲染后执行,可以返回一个清理函数
  3. useContext:用于在函数组件中访问 Context 对象,接受一个 Context 对象作为参数,返回该 Context 的当前值
  4. useMemo:用于在函数组件中缓存计算结果,避免重复计算,接受一个创建函数和一个依赖数组作为参数,返回该创建函数的最新返回值
  5. useCallback:用于在函数组件中缓存函数,避免不必要的重新渲染,接受一个内联回调和一个依赖数组作为参数,返回该回调的 memoized 版本
  6. useRef:用于在函数组件中创建和访问 ref 对象,接受一个初始值作为参数,返回一个可变的 ref 对象,其 current 属性指向初始值或最新的值
  7. useLayoutEffect:用于在函数组件中读取 DOM 布局并同步触发重渲染,与 useEffect 类似,但会在 DOM 更新后同步执行
  8. useReducer:用于在函数组件中管理复杂的状态逻辑,接受一个 reducer 函数和一个初始状态作为参数,返回一个状态变量和一个 dispatch 函数
  9. useImperativeHandle:用于在函数组件中自定义暴露给父组件的 ref 值,接受一个 ref 对象和一个创建函数作为参数,返回该创建函数的返回值,并赋给 ref 对象的 current 属性
  10. useDebugValue:用于在函数组件中显示自定义的 Hook 标签,接受一个标签值或者一个生成标签值的函数作为参数,在 React 开发者工具中显示
  11. useId:用于在函数组件中生成一个唯一的标识符,可以用于关联 label 和 input 等元素,或者生成 DOM 元素的 id 属性
  12. useSyncExternalStore:用于在函数组件中订阅和读取外部数据源,例如 Redux、MobX 等,它可以与 React 的并发渲染特性兼容,例如选择性 hydration 和 time slicing
  13. useDeferredValue:用于在函数组件中延迟更新某个值,直到浏览器有空闲时间,它可以避免因为频繁的状态更新而导致的性能问题

用法:

  • useState:用于在函数组件中引入状态,返回一个状态变量和一个更新状态的函数
import React, { useState } from 'react';

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

  const increment = () => setCount(count + 1);
  const decrement = () => setCount(count - 1);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

  • useEffect:用于在函数组件中执行副作用,接受一个函数作为参数,该函数会在组件渲染后执行,可以返回一个清理函数
import React, { useState, useEffect } from 'react';

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

  useEffect(() => {
    // 在组件挂载后获取数据
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));

    // 在组件卸载前进行清理工作
    return () => {
      // 取消订阅或清除计时器等
    };
  }, []);

  return (
    <div>
      {data ? (
        <ul>
          {data.map(item => (
            <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      ) : (
        <p>Loading data...</p>
      )}
    </div>
  );
}

  • useContext:用于在函数组件中访问 Context 对象,接受一个 Context 对象作为参数,返回该 Context 的当前值
import React, { useContext } from 'react';

const ThemeContext = React.createContext('light');

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return <button style={{ background: theme }}>Click Me</button>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}

  • useMemo:用于在函数组件中缓存计算结果,避免重复计算,接受一个创建函数和一个依赖数组作为参数,返回该创建函数的最新返回值
import React, { useState, useMemo } from 'react';

function ExpensiveCalculation({ number }) {
  // 使用useMemo缓存计算结果,只有当number发生变化时才重新计算
  const result = useMemo(() => {
    console.log('Calculating...');
    return number * 2;
  }, [number]);

  return <p>Result: {result}</p>;
}
  • useCallback:用于在函数组件中缓存函数,避免不必要的重新渲染,接受一个内联回调和一个依赖数组作为参数,返回该回调的 memoized 版本
import React, { useState, useCallback } from 'react';

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

  // 使用useCallback缓存回调函数,以避免每次渲染都创建新的函数
  const increment = useCallback(() => setCount(count + 1), [count]);
  const decrement = useCallback(() => setCount(count - 1), [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

  • useRef:用于在函数组件中创建和访问 ref 对象,接受一个初始值作为参数,返回一个可变的 ref 对象,其 current 属性指向初始值或最新的值
import React, { useRef } from 'react';

function FocusInput() {
  const inputRef = useRef(null);

  const handleClick = () => {
    // 使用inputRef.current来获取DOM元素的引用
    inputRef.current.focus();
  };

  return (
    <div>
      <input ref={inputRef} />
      <button onClick={handleClick}>Focus Input</button>
    </div>
  );
}

  • useLayoutEffect:用于在函数组件中读取 DOM 布局并同步触发重渲染,与 useEffect 类似,但会在 DOM 更新后同步执行
import React, { useState, useLayoutEffect, useRef } from 'react';

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

  useLayoutEffect(() => {
    // 获取DOM元素的宽度
    setWidth(ref.current.getBoundingClientRect().width);
  }, []);

  return (
    <div>
      <div ref={ref}>Measure this element</div>
      <p>Width: {width}px</p>
    </div>
  );
}

  • useReducer:用于在函数组件中管理复杂的状态逻辑,接受一个 reducer 函数和一个初始状态作为参数,返回一个状态变量和一个 dispatch 函数
import React, { 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:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  const increment = () => dispatch({ type: 'INCREMENT' });
  const decrement = () => dispatch({ type: 'DECREMENT' });

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

  • useImperativeHandle:用于在函数组件中自定义暴露给父组件的 ref 值,接受一个 ref 对象和一个创建函数作为参数,返回该创建函数的返回值,并赋给 ref 对象的 current 属性
import React, { useRef, useImperativeHandle, forwardRef } from 'react';

// 子组件
const ChildComponent = forwardRef((props, ref) => {
  const inputRef = useRef(null);

  // 使用useImperativeHandle来定义向父组件暴露的实例值
  useImperativeHandle(ref, () => ({
    focusInput: () => {
      inputRef.current.focus();
    },
  }));

  return <input ref={inputRef} />;
});

// 父组件
function ParentComponent() {
  const childRef = useRef(null);

  const handleClick = () => {
    // 调用子组件暴露的方法
    childRef.current.focusInput();
  };

  return (
    <div>
      <ChildComponent ref={childRef} />
      <button onClick={handleClick}>Focus Input</button>
    </div>
  );
}

  • useDebugValue:用于在函数组件中显示自定义的 Hook 标签,接受一个标签值或者一个生成标签值的函数作为参数,在 React 开发者工具中显示
import React, { useState, useDebugValue } from 'react';

function useCustomHook(initialValue) {
  const [value, setValue] = useState(initialValue);

  // 在React开发者工具中显示自定义hook标签
  useDebugValue(`Custom hook value: ${value}`);

  return [value, setValue];
}

function ExampleComponent() {
  const [count, setCount] = useCustomHook(0);

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

  • useId:用于在函数组件中生成一个唯一的标识符,可以用于关联 label 和 input 等元素,或者生成 DOM 元素的 id 属性
import { useId } from 'react';

function MyComponent() {
  // 生成一个唯一的标识符,例如 "input-0"
  const inputId = useId();

  return (
    <div>
      <label htmlFor={inputId}>Name</label>
      <input id={inputId} type="text" />
    </div>
  );
}

  • useSyncExternalStore:用于在函数组件中订阅和读取外部数据源,例如 Redux、MobX 等,它可以与 React 的并发渲染特性兼容,例如选择性 hydration 和 time slicing。它接受三个参数:subscribe、getSnapshot 和 getServerSnapshot,并返回数据源的当前值
import { useSyncExternalStore } from 'react';

function MyComponent() {
  // 订阅和读取 Redux store
  const state = useSyncExternalStore(
    // subscribe 函数,注册一个回调,在 store 变化时调用
    (callback) => store.subscribe(callback),
    // getSnapshot 函数,返回 store 的当前值
    () => store.getState(),
    // getServerSnapshot 函数(可选),返回服务端渲染时的 store 值
    () => store.getState()
  );

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => store.dispatch({ type: 'increment' })}>
        Increment
      </button>
    </div>
  );
}

  • useDeferredValue:用于在函数组件中延迟更新某个值,直到浏览器有空闲时间,它可以避免因为频繁的状态更新而导致的性能问题

import { useState, useDeferredValue } from 'react';

function MyComponent() {
  // 定义一个状态变量 text
  const [text, setText] = useState('');
  // 定义一个状态变量 count
  const [count, setCount] = useState(0);

  // 定义一个延迟更新的状态变量 deferredText
  const deferredText = useDeferredValue(text);
  // 定义一个延迟更新的状态变量 deferredCount
  const deferredCount = useDeferredValue(count, { timeoutMs: 1000 });

  return (
    <div>
      <input value={text} onChange={(e) => setText(e.target.value)} />
      <p>Text: {text}</p>
      <p>Deferred Text: {deferredText}</p>

      <p>Current Count: {count}</p>
      <p>Deferred Count: {deferredCount}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

全部评论

相关推荐

07-07 17:06
已编辑
深圳技术大学 golang
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务