基础语法
类组件(Class Components)
语法:基于 ES6 的
class
语法,继承React.Component
。功能:
- 可以使用生命周期方法(如
componentDidMount
,componentDidUpdate
等)。 - 可以定义和维护内部状态(
this.state
)。
- 可以使用生命周期方法(如
示例:
jsx
复制
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
componentDidMount() {
console.log("组件已挂载");
}
render() {
return <div>{this.state.count}</div>;
}
}
函数组件(Function Components)
语法:普通的 JavaScript 函数,通过返回 JSX 描述 UI。
演变:
- React 16.8 之前:函数组件是无状态的(没有
state
和生命周期方法),只能通过props
接收数据。 - React 16.8 之后:引入 Hooks(如
useState
,useEffect
),函数组件可以管理状态和副作用,功能与类组件几乎一致。
- React 16.8 之前:函数组件是无状态的(没有
示例:
jsx
复制
import { useState, useEffect } from 'react';
function MyComponent(props) {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("组件已挂载或更新");
}, [count]);
return <div>{count}</div>;
}
主要区别
特性 | 类组件 | 函数组件(含 Hooks) |
---|---|---|
状态管理 | 通过 this.state 和 setState | 通过 useState 等 Hooks |
生命周期 | 使用生命周期方法(如 componentDidMount ) | 使用 useEffect 模拟生命周期 |
代码简洁性 | 代码较长,需要处理 this 绑定 | 代码更简洁,无 this 问题 |
复用性 | 通过高阶组件(HOC)或 Render Props | 通过自定义 Hooks 更灵活 |
React 推荐 | 旧项目常见,但逐渐被取代 | 新项目首选,官方推荐未来方向 |
4. 为什么函数组件成为主流?
- Hooks 的引入:解决了函数组件无法管理状态的痛点。
- 更简洁的代码:避免了类组件中的
this
绑定问题和冗余代码。 - 更好的逻辑复用:自定义 Hooks 比 HOC 或 Render Props 更直观。
- 性能优化:React 团队优化了函数组件的更新机制(如
React.memo
)。
5. 如何选择?
- 新项目:优先使用函数组件 + Hooks。
- 旧项目维护:逐步将类组件迁移到函数组件(无需强制替换)。
- 学习路径:建议直接学习函数组件,除非需要维护旧代码。
函数组件写法
类型定义 和 函数组件的声明方式。
1. React.FC
(React.FunctionComponent) 的使用:
React.FC
是 React 提供的一个类型别名,用于声明函数组件,它提供了一些默认的类型检查和自动推导:
tsx复制编辑const LogoGather: React.FC<LogoGatherProps> = ({ ... }) => {
// 组件内容
};
React.FC
或 React.FunctionComponent
是 TypeScript 中的一种写法,用来指定一个函数是一个 React 组件,并且接受某些 props。它的功能包括:
- 推导
children
类型:使用React.FC
后,children
会自动成为该组件的 props(类型为ReactNode
),即使没有显式地定义children
属性。 - 提供默认的返回类型
JSX.Element
:使用React.FC
可以隐式地推导组件的返回值类型为JSX.Element
。
例如:
tsx复制编辑const LogoGather: React.FC<LogoGatherProps> = ({ top, left, image }) => {
return <div>{image}</div>;
};
- 这里
LogoGather
组件将自动推导出children
和返回JSX.Element
,并且如果没有传递children
,TypeScript 会自动推导出相关类型。
2. export default function Home(): JSX.Element
的写法:
这个写法没有使用 React.FC
,直接声明函数组件并返回 JSX.Element
。如果你的组件不需要处理 children
,并且只涉及一些普通的 props
,这种方式更加简洁。
例如:
tsx复制编辑export default function Home({ title }: { title: string }): JSX.Element {
return <h1>{title}</h1>;
}
这种写法没有显式声明 children
,如果你的组件没有 children
的需求,那么不使用 React.FC
是完全可以的,而且会更简洁。
3. React.FC
的优缺点:
优点:
- 自动推导
children
类型:当你使用React.FC
时,它会自动将children
作为默认属性添加到组件的 props 中,省去了显式声明children
的麻烦。 - 类型推导自动提供:它自动推导返回值为
JSX.Element
,可以节省一些类型声明。
缺点:
- 有时不必要的冗余:如果你不打算使用
children
,或者不需要自动推导返回类型为JSX.Element
,React.FC
可能就显得有些冗余。 - 一些类型问题:某些情况下,
React.FC
会导致一些类型推导问题,比如如果你不打算传递children
,可能会遇到类型冲突。
4. 总结:
- 如果你的组件 需要
children
或者你希望 自动推导JSX.Element
,那么可以使用React.FC
,这样写起来也会更方便。 - 如果组件不需要
children
,并且你只关心 props 类型和返回值类型,直接使用function
声明并指定返回JSX.Element
也是完全有效的,而且语法更加简洁。
两者写法没有绝对的优劣,关键在于项目的需求和团队的偏好。如果你需要更简洁的代码,并且没有 children
,可以直接用 export default function
,如果你希望使用 children
或者倾向于使用 React.FC
的默认行为,也可以采用 React.FC
。
条件渲染
基础语法