React Hooks 完全指南
React Hooks 是 React 16.8 中引入的一项重要特性,它让你可以在不编写 class 的情况下使用 state 和其他 React 特性。本文将详细介绍所有内置 Hooks 的使用方法、自定义 Hook 的创建,以及 Hook 使用中的注意事项。
为什么需要 Hooks
在 Hooks 出现之前,组件逻辑复用主要依赖高阶组件(HOC)和渲染属性(Render Props)模式,这些模式会导致组件嵌套地狱问题。而 Hooks 通过函数组合的方式解决了这个问题。
基础 Hooks
useState
useState
是最基本的 Hook,它让函数组件拥有状态。
import React, { useState } from 'react'
function Counter() {
// 声明一个新的状态变量,我们叫它"count"
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
useEffect
useEffect
让你在函数组件中执行副作用操作,如数据获取、订阅或手动更改 DOM 等。
import React, { useState, useEffect } from 'react'
function Example() {
const [count, setCount] = useState(0)
// 类似于componentDidMount和componentDidUpdate:
useEffect(() => {
// 更新文档标题
document.title = `You clicked ${count} times`
// 返回一个清除函数(可选)
return () => {
document.title = 'React App'
}
}, [count]) // 仅在count更改时执行
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
useContext
useContext
接收一个 Context 对象,并返回该 Context 的当前值。
import React, { useContext } from 'react'
const ThemeContext = React.createContext('light')
function ThemedButton() {
const theme = useContext(ThemeContext)
return <button className={theme}>Themed Button</button>
}
高级 Hooks
useReducer
useReducer
是 useState 的替代方案,适用于复杂的状态逻辑。
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:
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>
</>
)
}
自定义 Hooks
自定义 Hook 是一种重用状态逻辑的方法,而不需要添加更多的组件。
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
}
// 使用自定义Hook
function ScreenInfo() {
const windowSize = useWindowSize()
return (
<div>
Window width: {windowSize.width}px
<br />
Window height: {windowSize.height}px
</div>
)
}
Hook 使用规则
使用 Hook 需要遵循两条规则:
- 只在函数组件的顶层调用 Hook
- 只在 React 函数组件或自定义 Hook 中调用 Hook
结论
React Hooks 彻底改变了我们编写 React 组件的方式,使代码更加简洁、可读性更强,同时也便于测试和复用。通过合理使用 Hook,我们可以构建出更加模块化和可维护的 React 应用。
Last updated on