--- title: 不要在组件内部定义组件 impact: HIGH impactDescription: 阻止每次渲染时重新挂载 tags: rerender, components, remount, performance --- ## 不要在组件内部定义组件 **影响:高(阻止每次渲染时重新挂载)** 在另一个组件内部定义组件,会在每次渲染时创建一个新的组件类型。React 每次看到的是不同的组件,因此会完全重新挂载它,销毁所有状态和 DOM。 开发者这样做的一个常见原因是为了在不传递 props 的情况下访问父组件的变量。请始终改用传递 props 的方式。 **错误写法(每次渲染都重新挂载):** ```tsx function UserProfile({ user, theme }) { // 为了访问 `theme` 而在内部定义 - 错误 const Avatar = () => ( ) // 为了访问 `user` 而在内部定义 - 错误 const Stats = () => (
{user.followers} followers {user.posts} posts
) return (
) } ``` 每次 `UserProfile` 渲染时,`Avatar` 和 `Stats` 都是新的组件类型。React 会卸载旧实例并挂载新实例,丢失所有内部状态,重新运行 effect,并重建 DOM 节点。 **正确写法(改为传递 props):** ```tsx function Avatar({ src, theme }: { src: string; theme: string }) { return ( ) } function Stats({ followers, posts }: { followers: number; posts: number }) { return (
{followers} followers {posts} posts
) } function UserProfile({ user, theme }) { return (
) } ``` **此错误的症状:** - 输入框在每次按键后失去焦点 - 动画意外重新开始 - `useEffect` 的清理/设置逻辑在每次父组件渲染时执行 - 组件内的滚动位置重置