1.1 设计哲学演进
// 传统Class组件 vs Hooks范式
class Counter extends React.Component {
state = { count: 0 } // 状态管理受限
componentDidMount() { // 生命周期割裂
document.title = `Count: ${this.state.count}`
}
componentDidUpdate() {
document.title = `Count: ${this.state.count}`
}
}
function Counter() {
const [count, setCount] = useState(0) // 线性状态管理
useEffect(() => { // 逻辑聚合
document.title = `Count: ${count}`
}, [count]) // 精准依赖控制
}
1.2 生命周期映射表(企业级实践)
Class 生命周期 | Hook 实现方案 | 典型场景 | 注意事项 |
---|
constructor | useState惰性初始化 | 大数据量初始化 | 避免直接计算复杂初始值 |
componentDidMount | useEffect(fn, []) | 订阅事件/初始化请求 | 清理函数必须返回 |
componentDidUpdate | useEffect(fn, [deps]) | 依赖项变化处理 | 精确控制依赖数组 |
shouldComponentUpdate | React.memo + useMemo | 复杂组件渲染优化 | 避免过度优化 |
getDerivedStateFromProps | useState + useEffect | Props驱动状态更新 | 使用useDerivedState自定义Hook |
1.3 渐进式重构策略
// 新旧组件共存方案
class LegacyComponent extends React.Component {
// 原有逻辑...
}
function NewComponent() {
const [state] = useState(/*...*/)
useEffect(/*...*/)
return (
<LegacyComponent
{...props}
onUpdate={/* 桥接逻辑 */}
/>
)
}
第二章 核心Hooks深度解析
2.1 useState
// Tab.tsx 复杂状态管理
type NavigationState = {
routes: Array<{ key: string; title: string }>
index: number
}
const [navState, setNavState] = useState<NavigationState>(() => ({
routes: [
{ key: 'dashboard', title: '控制台' },
{ key: 'analytics', title: '分析' }
],
index: sessionStorage.getItem('lastTabIndex') || 0
}))
// 安全更新模式
const updateIndex = (newIndex: number) => {
setNavState(prev => ({
...prev,
index: Math.max(0, Math.min(newIndex, prev.routes.length - 1))
}))
}
2.2 useEffect全场景指南
// Navigator.tsx 路由监听最佳实践
const navigation = useNavigation()
useEffect(() => {
const subscription = navigation.addListener('state', handleStateChange)
const timer = setInterval(() => {
analytics.sendHeartbeat()
}, 5000)
return () => {
subscription.remove()
clearInterval(timer)
analytics.flush()
}
}, [navigation, analytics]) // 严格依赖声明
// 竞态处理模式
useEffect(() => {
let isCurrent = true
fetchData().then(data => {
if (isCurrent) setData(data)
})
return () => { isCurrent = false }
}, [query])
2.3 useRef高级应用
// BarrageItem.tsx 动画与DOM操作
const ref = useRef<Animated.View>(null)
const startPos = useRef(new Animated.Value(0)).current
useLayoutEffect(() => {
Animated.timing(startPos, {
toValue: 1,
duration: 300,
useNativeDriver: true
}).start()
}, [])
const handleLayout = useCallback(() => {
ref.current.measure((x, y) => {
collisionDetection.registerPosition(x, y)
})
}, [])
return <Animated.View
ref={ref}
onLayout={handleLayout}
style={{ transform: [{ translateX: startPos }] }}
/>
第三章 性能优化体系
3.1 渲染优化矩阵
// SliderEntry.tsx 记忆化优化
const SliderEntry = React.memo(({ data }: Props) => {
const formattedDate = useMemo(
() => formatDate(data.timestamp, 'YYYY-MM-DD HH:mm'),
[data.timestamp]
)
const handlePress = useCallback(() => {
navigation.navigate('Detail', { id: data.id })
}, [data.id])
return (
<Touchable onPress={handlePress}>
<Text>{formattedDate}</Text>
</Touchable>
)
})
3.2 Redux性能优化
// HomeTabs.tsx 现代Redux实践
const dispatch = useDispatch()
const { channels, loading } = useSelector((state: RootState) => ({
channels: selectFilteredChannels(state),
loading: state.loading.effects.channels.fetch
}), shallowEqual)
// Reselect优化selector
const selectFilteredChannels = createSelector(
[(state: RootState) => state.channels.data],
(channels) => channels.filter(c => c.isActive)
)
第四章 自定义Hook开发规范
4.1 生命周期模拟Hook
// useDerivedState.ts - 替代getDerivedStateFromProps
function useDerivedState<T>(props: T, compute: (prev?: T) => T): [T, Dispatch<SetStateAction<T>>] {
const [state, setState] = useState(() => compute(props))
useLayoutEffect(() => {
if (!Object.is(props, state)) {
setState(compute(props))
}
}, [props])
return [state, setState]
}
// 使用案例
const [derivedState] = useDerivedState(props, (prevProps) => {
return props.value !== prevProps?.value
? calculateState(props.value)
: prevState
})
4.2 复杂状态管理Hook
// useUndoableState.ts 可撤销状态
function useUndoableState<T>(initialValue: T) {
const [state, setState] = useState(initialValue)
const [history, setHistory] = useState<T[]>([])
const [pointer, setPointer] = useState(-1)
const undo = useCallback(() => {
setPointer(p => (p > 0 ? p - 1 : p))
}, [])
const redo = useCallback(() => {
setPointer(p => (p < history.length - 1 ? p + 1 : p))
}, [history])
const updateState = useCallback((newValue: T) => {
setHistory(prev => [...prev.slice(0, pointer + 1), newValue])
setPointer(p => p + 1)
setState(newValue)
}, [pointer])
return [state, updateState, { undo, redo, history }] as const
}