一个典型的 React 项目文件目录结构如下:
my-app/
README.md
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
serviceWorker.js
api/ // API 相关文件
components/ // 组件文件
constants/ // 常量目录
containers/ // 容器组件目录
images/ // 图片资源
routes/ // 路由文件
styles/ // 样式文件
tests/ // 测试文件
utils/ // 工具函数目录
每个文件的主要作用:
- public/index.html:HTML 模板
- src/index.js:入口文件
- src/App.js:根组件
- src/routes/index.js:路由配置
- src/components/:React 组件目录,存放可重用的组件
- src/containers/:容器组件目录,用于连接组件和 Redux 状态
- src/api/:API 调用文件目录
- src/utils/:工具函数目录,可重用的工具函数
- src/constants/:常量目录
- src/styles/:样式文件目录
- src/tests/:测试文件目录
- node_modules/:npm 包依赖
- package.json:项目配置文件
总结来说,React 项目文件的主要作用是:
各组件、容器、views 等的文件用于编写 UI
- service 和 api 用于和后端交互
- constants 和 utils 用于存放一些可重用的常量与工具方法
- routes 配置路由信息
- styles 包含样式文件
- tests 包含测试文件
- public 提供 HTML 模板等静态资源
参考:容器组件
容器组件(Container Component)是 React 中的一个概念。它指的是连接 Redux state 与 UI 组件(Presentational Component)的中间件组件。
容器组件的主要作用是:
- 从 Redux state 中读取数据
- 分发 action 来修改 Redux state
- 订阅 Redux state 的改变
- 将数据和回调作为 props 传递给 UI 组件
相比之下,UI 组件主要负责 UI 的呈现,不直接操作 Redux。
举个例子,有这样一个 UI 组件:
// UserInfo.js
const UserInfo = (props) => {
const { user, onSave } = props;
return (
<div>
<span>{user.name}</span>
<button onClick={() => onSave(user)}>Save</button>
</div>
);
}
然后,这里有一个容器组件将其连接到 Redux:
// UserInfoContainer.js
import { connect } from 'react-redux';
import { saveUser } from '../actions/user';
import UserInfo from './UserInfo';
const mapStateToProps = (state) => ({
user: state.user
});
const mapDispatchToProps = (dispatch) => ({
onSave: (user) => dispatch(saveUser(user))
});
export default connect(mapStateToProps, mapDispatchToProps)(UserInfo);
UserInfoContainer 这个容器组件将 Redux state 中的 user 数据作为 props 传给 UserInfo UI 组件。同时,它也将 saveUser action 的 dispatch 方法作为 onSave props 传下去。
所以,通过容器组件 UserInfoContainer,UserInfo UI 组件可以获取 Redux state 并触发 action,而自身不需要直接操作 Redux,只关注 UI 的呈现。
这就是 React 中容器组件和 UI 组件的区别与关系。容器组件负责与 Redux “对接”,UI 组件专注于 UI 的呈现。这种分离可以使我们的代码更加清晰易维护。