跳转到内容

React Hooks

来自代码酷

React Hooks 是 React 16.8 引入的一项特性,允许开发者在函数组件中使用状态(state)和其他 React 特性(如生命周期方法),而无需编写类组件。Hooks 提供了一种更简洁、更直观的方式来管理组件逻辑,同时保持代码的可复用性和可维护性。

简介[编辑 | 编辑源代码]

在 React 之前,函数组件是无状态的,只能作为“纯函数”使用。如果需要状态或生命周期方法,开发者必须使用类组件。Hooks 的出现改变了这一现状,使得函数组件能够拥有与类组件相同的功能。

Hooks 的核心思想是:

  • **无需类组件**:直接在函数组件中使用状态和副作用。
  • **逻辑复用**:通过自定义 Hooks 封装和复用组件逻辑。
  • **更清晰的代码结构**:避免类组件中的复杂嵌套和生命周期方法。

基本 Hooks[编辑 | 编辑源代码]

useState[编辑 | 编辑源代码]

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

  
import React, { useState } from 'react';  

function Counter() {  
  const [count, setCount] = useState(0); // 初始值为 0  

  return (  
    <div>  
      <p>当前计数: {count}</p>  
      <button onClick={() => setCount(count + 1)}>增加</button>  
    </div>  
  );  
}
  • `count`:当前状态值。
  • `setCount`:更新状态的函数。

useEffect[编辑 | 编辑源代码]

`useEffect` 用于处理副作用(如数据获取、订阅、手动 DOM 操作等),相当于类组件中的 `componentDidMount`、`componentDidUpdate` 和 `componentWillUnmount` 的组合。

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

function Timer() {  
  const [seconds, setSeconds] = useState(0);  

  useEffect(() => {  
    const interval = setInterval(() => {  
      setSeconds(prevSeconds => prevSeconds + 1);  
    }, 1000);  

    return () => clearInterval(interval); // 清理函数  
  }, []); // 空依赖数组表示只在组件挂载时执行  

  return <p>已运行: {seconds} </p>;  
}
  • **依赖数组**(第二个参数):
 * 空数组 `[]`:仅在组件挂载时运行一次。  
 * 包含变量 `[dep1, dep2]`:当依赖项变化时重新运行。  

进阶 Hooks[编辑 | 编辑源代码]

useContext[编辑 | 编辑源代码]

`useContext` 用于在组件树中共享数据,避免逐层传递 props。

  
import React, { useContext } from 'react';  

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

function ThemedButton() {  
  const theme = useContext(ThemeContext);  
  return <button style={{ background: theme === 'dark' ? '#333' : '#fff' }}>按钮</button>;  
}

useReducer[编辑 | 编辑源代码]

`useReducer` 是 `useState` 的替代方案,适用于复杂状态逻辑。

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

自定义 Hooks[编辑 | 编辑源代码]

自定义 Hooks 是封装可复用逻辑的函数,命名需以 `use` 开头。

  
import { useState, useEffect } from 'react';  

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

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

  return data;  
}  

function UserProfile({ userId }) {  
  const user = useFetch(`/api/users/${userId}`);  
  return user ? <div>{user.name}</div> : <div>加载中...</div>;  
}

实际案例[编辑 | 编辑源代码]

表单处理[编辑 | 编辑源代码]

使用 `useState` 管理表单输入:

  
function LoginForm() {  
  const [email, setEmail] = useState('');  
  const [password, setPassword] = useState('');  

  const handleSubmit = (e) => {  
    e.preventDefault();  
    console.log({ email, password });  
  };  

  return (  
    <form onSubmit={handleSubmit}>  
      <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />  
      <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />  
      <button type="submit">登录</button>  
    </form>  
  );  
}

性能优化[编辑 | 编辑源代码]

useMemo 和 useCallback[编辑 | 编辑源代码]

  • `useMemo`:缓存计算结果。
  • `useCallback`:缓存函数。
  
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);  
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);

总结[编辑 | 编辑源代码]

React Hooks 提供了一种更简洁的方式来编写 React 组件,同时支持逻辑复用和更好的代码组织。以下是关键点:

  • **`useState`**:管理组件状态。
  • **`useEffect`**:处理副作用。
  • **`useContext`**:共享全局数据。
  • **`useReducer`**:复杂状态管理。
  • **自定义 Hooks**:封装可复用逻辑。

通过合理使用 Hooks,可以显著提升 React 应用的开发效率和可维护性。