react的hook介绍

React Hooks 是 React 16.8 引入的一组函数,用于在函数组件中使用状态和生命周期功能。

Hooks 提供了一种更简洁、更灵活的方式来管理组件的状态和副作用。以下是 React 中常见的 Hooks 及其详细用法说明:

1. useState

用于在函数组件中添加状态

const [state, setState] = useState(initialValue);

initialValue: 状态的初始值

state: 当前状态值

setState: 更新状态的函数

import React, { useState } from 'react';

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

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

2. useEffect

用于处理副作用(如数据获取、订阅、手动 DOM 操作等)

用法

useEffect(() => {
  // 副作用逻辑
  return () => {
    // 清理逻辑(可选)
  };
}, [dependencies]);

dependencies: 依赖数组,决定何时重新执行副作用。如果为空数组 [],则只会在组件挂载和卸载时执行一次

import React, { useState, useEffect } from 'react';

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

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]); // 仅当 count 改变时更新标题

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

3. useContext

用于在组件树中访问上下文(Context)的值,避免逐层传递 props

用法

const value = useContext(MyContext);

MyContext: 创建的 Context 对象

import React, { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

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

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

4. useReducer

用于复杂的状态管理,类似于 Redux 的 reducer

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

reducer: 一个纯函数,定义如何根据当前状态和动作更新状态

initialState: 初始状态

dispatch: 触发状态更新的函数

import React, { useReducer } from 'react';

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, { count: 0 });

  return (
    <div>
      Count: {state.count}
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </div>
  );
}

5. useCallback

用于缓存回调函数,避免不必要的重新创建

const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

callback: 要缓存的函数

dependencies: 依赖数组,决定何时重新创建函数

import React, { useState, useCallback } from 'react';

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

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

  return <Child onIncrement={increment} />;
}

function Child({ onIncrement }) {
  console.log('Child rendered');
  return <button onClick={onIncrement}>Increment</button>;
}

6. useMemo

用于缓存计算结果,避免不必要的重新计算

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

computeFunction: 计算函数

dependencies: 依赖数组,决定何时重新计算

import React, { useState, useMemo } from 'react';

function ExpensiveCalculation({ a, b }) {
  const result = useMemo(() => {
    return a * b;
  }, [a, b]);

  return <div>Result: {result}</div>;
}

7. useRef

用于直接访问 DOM 元素或存储可变值

const refContainer = useRef(initialValue);

initialValue: 初始值

import React, { useRef } from 'react';

function TextInputWithFocusButton() {
  const inputEl = useRef(null);

  const onButtonClick = () => {
    inputEl.current.focus();
  };

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

8. useImperativeHandle

自定义暴露给父组件的实例值

useImperativeHandle(ref, createHandle, [deps]);

ref: 父组件传递的 ref

createHandle: 返回自定义实例值的函数

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

const Child = forwardRef((props, ref) => {
  const inputRef = useRef();

  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));

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

function Parent() {
  const childRef = useRef();

  return (
    <>
      <Child ref={childRef} />
      <button onClick={() => childRef.current.focus()}>Focus Input</button>
    </>
  );
}

9. useLayoutEffect

类似于 useEffect,但在 DOM 更新后同步执行

useLayoutEffect(() => {
  // 副作用逻辑
  return () => {
    // 清理逻辑(可选)
  };
}, [dependencies]);
import React, { useLayoutEffect, useRef } from 'react';

function MeasureExample() {
  const divRef = useRef();

  useLayoutEffect(() => {
    console.log(divRef.current.getBoundingClientRect());
  });

  return <div ref={divRef}>Hello, world</div>;
}

10. useDebugValue

用于调试自定义 Hook

useDebugValue(value);
import { useState, useDebugValue } from 'react';

function useCustomHook() {
  const [isOnline, setIsOnline] = useState(true);
  useDebugValue(isOnline ? 'Online' : 'Offline');
  return isOnline;
}

总结

React Hooks 提供了强大的工具来管理状态和副作用,使函数组件更加灵活和强大。常用的 Hooks 包括:

  • 状态管理:useStateuseReducer
  • 副作用处理:useEffectuseLayoutEffect
  • 性能优化:useCallbackuseMemo
  • 引用和操作:useRefuseImperativeHandle
  • 调试:useDebugValue
posted @ 2025-03-17 16:51  zzwlong  阅读(132)  评论(0)    收藏  举报