export default function?在react中在前面还是后面呢?
好的!我将通过几个具体场景的代码示例,展示不同 export default
使用方式的适用情况,并给出推荐实践。
场景 1:基础组件(推荐直接导出)
适用情况:简单组件,无需额外处理
// 方式A: 直接导出(最简洁)
export default function Button({ children, onClick }) {
return <button onClick={onClick}>{children}</button>;
}
// 方式B: 先声明后导出(略显冗余)
function Button({ children, onClick }) {
return <button onClick={onClick}>{children}</button>;
}
export default Button;
场景 2:需要 HOC 包装的组件
适用情况:需要被 memo
/withRouter
等包裹
import { memo } from 'react';
// 1. 先声明组件
function ExpensiveList({ items }) {
return (
<ul>
{items.map(item => <li key={item.id}>{item.text}</li>)}
</ul>
);
}
// 2. 用memo包裹后导出
export default memo(ExpensiveList);
场景 3:需要添加静态属性的组件
适用情况:需要给组件附加 propTypes
/defaultProps
等
import PropTypes from 'prop-types';
// 1. 先声明组件
function Avatar({ src, size }) {
return <img src={src} style={{ width: size }} alt="User Avatar" />;
}
// 2. 添加静态属性
Avatar.propTypes = {
src: PropTypes.string.isRequired,
size: PropTypes.number
};
Avatar.defaultProps = {
size: 40
};
// 3. 最后导出
export default Avatar;
是的!使用 const
声明组件时,你可以直接在声明时附加静态属性,这样可以更紧凑地组织代码。以下是优化后的写法:
优化版本(推荐)
import PropTypes from 'prop-types';
// 用 const 声明并立即附加属性
const Avatar = ({ src, size }) => (
<img src={src} style={{ width: size }} alt="User Avatar" />
);
// 直接在同一个语句块内添加静态属性
Avatar.propTypes = {
src: PropTypes.string.isRequired,
size: PropTypes.number
};
Avatar.defaultProps = {
size: 40
};
export default Avatar;
进一步简化(ES2022+ 支持)
如果你使用的是现代 JavaScript(ES2022+),还可以用 类字段(class fields) 风格的静态属性:
const Avatar = ({ src, size = 40 }) => (
<img src={src} style={{ width: size }} alt="User Avatar" />
);
// 类字段风格(需确保编译环境支持)
Avatar.propTypes = {
src: PropTypes.string.isRequired,
size: PropTypes.number
};
export default Avatar;
关键区别说明
特性 | function 声明写法 | const 箭头函数写法 |
---|---|---|
Hoisting | 可提升(可在声明前调用) | 不可提升(必须先声明后使用) |
静态属性 | 必须在声明后单独附加 | 可在同一代码块内附加 |
this 绑定 | 有自己的 this 上下文 | 继承外层 this (通常为 undefined ) |
适用场景 | 需要组件名称在文件内可提升时使用 | 现代 React 项目的推荐写法 |
为什么推荐 const
写法?
- 更符合函数式编程风格(React 组件本质是函数)
- 避免意外的
this
绑定问题 - 与 Hooks 风格更一致
- 代码组织更紧凑(特别是配合现代工具链时)
⚠️ 注意:如果组件中需要使用
forwardRef
,则必须用const
声明:const Avatar = React.forwardRef((props, ref) => { ... });
场景 4:需要调试中间状态的组件
适用情况:开发时可能需要临时打印 props
// 1. 先声明组件
function UserCard(props) {
// 开发时调试
if (process.env.NODE_ENV === 'development') {
console.log('UserCard props:', props);
}
return <div>{props.username}</div>;
}
// 2. 导出前可添加其他逻辑
export default UserCard;
场景 5:动态导出不同组件
适用情况:根据条件导出不同实现
// 1. 声明多个组件
function MobileLayout() { return /*...*/ }
function DesktopLayout() { return /*...*/ }
// 2. 根据条件动态导出
export default window.innerWidth < 768 ? MobileLayout : DesktopLayout;
最佳实践总结
场景 | 推荐写法 | 原因 |
---|---|---|
普通组件 | export default function Comp() {} | 简洁直观 |
需要包装的组件 | 先声明后导出 + HOC | 便于扩展 |
需要静态属性 | 先声明后导出 | 方便添加属性 |
需要调试 | 先声明后导出 | 便于插入调试代码 |
动态导出 | 先声明后导出 | 灵活控制导出内容 |
通用建议:
- 项目内保持统一风格
- 80% 的情况直接用
export default function
即可 - 当看到需要 “加工” 组件时,切换到先声明后导出模式
是否需要我针对某个具体场景展开更详细的实现?