React技术栈实现大众点评Demo-项目结构探究
项目截图
React+Redux项目结构探索整理学习react技术栈相关知识,在写了一个电商AppDemo后,开始思考起该如何高效的组织react项目的项目结构。 按照类型划分(redux官方实例采用的方式)目录结构如下: app/ actions/ a.js b.js components/ a.js b.js containers/ a.js b.js reducers/ a.js b.js index.js 这是官网demo中的示例写法,在刚开始学习的时候,我的很多学习demo也是按照这种方式去组织的代码结构 其中最主要的就是在每次增加一个新的功能的开发一个功能模块的时候,你要各种目录下操作。container里写容器,component里写该功能模块的组件。action、reducer...一系列都得改动。 所以如此这般的频繁的切换路径,修改不同的文件。当项目比较大的时候,这种目录结构是非常不方便的 按照功能划分按照功能模块划分其实就是目前我这个项目所用到的。当然,此项目目录结构真的不咋滴。乱七八糟。
feature1/ components/ actions.js container.js index.js reducer.js feature2/ components/ actions.js container.js index.js reducer.js index.js rootReducer.js 在《深入浅出React和Redux》一本书中,推荐的就是这种方式,真正的做到组件化,划分到组件、状态和行为都在同一个文件夹里。方便开发,也易于扩展。组件中只要一个index.js去暴露出接口就行。 但是这种结构存在一个问题,就是随着应用扩大(即使我这个应用没有几个页面,但是依旧存在了问题)。 因为redux会将整个应用状态作为一个store来管理,不同的模块之间可以共享state中的任何一个部分,这种情况下,可能feature1中的dispatch会影响到feature2中的reducer,正如这个demo中出现的。 这种情况下,不同模块间的功能被耦合到了一起。 Ducksgithub上这么介绍的:A proposal for bundling reducers,action types and actions when using Redux. 所以这里,我们翻一下。 在创建redux应用时,按照功能性划分,每次会都添加 // widgets.js // Actions const LOAD = 'my-app/widgets/LOAD'; const CREATE = 'my-app/widgets/CREATE'; const UPDATE = 'my-app/widgets/UPDATE'; const REMOVE = 'my-app/widgets/REMOVE'; // Reducer export default function reducer(state = {},action = {}) { switch (action.type) { // do reducer stuff default: return state; } } // Action Creators export function loadWidgets() { return { type: LOAD }; } export function createWidget(widget) { return { type: CREATE,widget }; } export function updateWidget(widget) { return { type: UPDATE,widget }; } export function removeWidget(widget) { return { type: REMOVE,widget }; } 规则一个模块 ...
上述规则也推荐用在可重用的redux 库中用来组织{actionType,action,reducer} 本质上是以应用的状态作为模块的划分依据,而不是以界面功能作为划分模块的依据。这样,管理相同状态的依赖都在同一个文件中,不管哪个容器组件需要使用这部分状态,只需要在这个组件中引入这个状态对应的文件即可。 整体的目录结构如下: components/ (应用级别的通用组件) containers/ feature1/ components/ (功能拆分出的专用组件) feature1.js (容器组件) index.js (feature1对外暴露的接口) redux/ index.js (combineReducers) module1.js (reducer,action types,actions creators) module2.js (reducer,actions creators) index.js 在前两种项目结构中,当container需要使用actions时,可以通过import * as actions from 'path/to/actions.js'方式,一次性把一个action文件中的所有action creators都引入进来。 // widget.js // Actions export const types = { const LOAD : 'widget/LOAD',const CREATE : 'widget/CREATE',const UPDATE : 'widget/UPDATE',const REMOVE : 'widget/REMOVE' } const initialState = { widget: null,isLoading: false,} // Reducer export default function reducer(state = initialState,action = {}) { switch (action.type) { types.LOAD: //... types.CREATE: //... types.UPDATE: //... types.REMOVE: //... default: return state; } } // Action Creators export actions = { loadWidget: function() { return { type: types.LOAD }; },createWidget: createWidget(widget) { return { type: types.CREATE,widget }; },updateWidget: function(widget) { return { type: types.UPDATE,removeWidget: function(widget) { return { type: types.REMOVE,widget }; } } 这样,我们在container中使用actions时,可以通过import { actions } from 'path/to/module.js'引入, 下一个全栈blog的demo将会采用第三种方式去组织代码 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |