React Hooks 深入指南

React Hooks 是 React 16.8 引入的新特性,它让函数组件也能拥有状态和生命周期。本文将深入讲解 React Hooks 的使用方法和最佳实践。

useState - 状态管理

useState 是最基础的 Hook,用于在函数组件中添加状态:

import { useState } from 'react'

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

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

useEffect - 副作用处理

useEffect 用于处理副作用,如数据获取、订阅、DOM 操作等:

import { useState, useEffect } from 'react'

function UserProfile({ userId }) {
  const [user, setUser] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    setLoading(true)
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        setUser(data)
        setLoading(false)
      })
    
    // 清理函数
    return () => {
      // 取消请求等清理操作
    }
  }, [userId])  // 依赖数组

  if (loading) return <div>Loading...</div>
  return <div>{user.name}</div>
}

useContext - 上下文共享

useContext 用于跨组件共享数据:

import { createContext, useContext } from 'react'

const ThemeContext = createContext('light')

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

function Toolbar() {
  const theme = useContext(ThemeContext)
  return <div>Current theme: {theme}</div>
}

useCallback 和 useMemo

这两个 Hook 用于性能优化:

  • useCallback:缓存函数引用
  • useMemo:缓存计算结果
const memoizedCallback = useCallback(() => {
  doSomething(a, b)
}, [a, b])

const memoizedValue = useMemo(() => {
  return computeExpensiveValue(a, b)
}, [a, b])

useReducer - 复杂状态管理

当状态逻辑复杂时,useReducer 比 useState 更适合:

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 (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
    </>
  )
}

自定义 Hook

自定义 Hook 是复用逻辑的最佳方式:

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

  const setValue = (value) => {
    setStoredValue(value)
    window.localStorage.setItem(key, JSON.stringify(value))
  }

  return [storedValue, setValue]
}

// 使用
const [theme, setTheme] = useLocalStorage('theme', 'light')

Hooks 使用规则

  1. 只在函数组件或自定义 Hook 中调用 Hooks
  2. 只在最顶层调用 Hooks,不要在循环、条件或嵌套函数中调用
  3. 自定义 Hook 的名称必须以 use 开头

总结

React Hooks 极大地简化了 React 开发,让代码更易读、更易测试。掌握 Hooks 是成为优秀 React 开发者的必经之路。

← 返回博客列表