背景
我对Angular 1.x有一年半的经验,转向React / Redux进行Angular不适合的项目。我已经读过某个地方,React是来自Angular的“基本上所有指令”,这太棒了,因为我认为指令是Angular最强大的功能。然而,在React / Redux与Angular中创建应用程序的心态也非常不同(比如创建数据主干然后再代表它的想法,而不是Angular的集中式方法)。我有很多困难要理解。
设置
应用程序正在Electron中编写,使用以下作为树苗:https://github.com/chentsulin/electron-react-boilerplate
我的root reducer看起来像这样:
root: {
Home: Object, // Basic homepage tab
Gallery: [ // Gallery tab
{ // A single instance of "photo" object
filename: String,
metadata: Object,
error: Object
}
]
}
Gallery具有打开目录的功能。它扫描用户选择的目录并在那里查找照片,接收一组文件名。然后它应该将每张照片作为一个组件呈现,每张照片在用文件名初始化后,应该启动自己的阅读图片元数据并在页面上呈现自己信息的过程。
我得到了这一点,我可以在页面上呈现所有文件名没问题。但是,我需要将文件名转换为渲染和处理过的照片。那就是我遇到麻烦的地方。
问题
照片有一些属性,如上图所示。它还有一些操作(例如new
,update
,delete
等。属性和操作需要绑定到组件。通常,对于页面大小的组件,这是在JS文件中完成的,该文件执行所有connect
和bindActionCreators
调用。然后将此JS文件包含在反应路由器中,并显示为页面。
照片不是网页。它们意味着是可重用的组件,页面上有很多组件。如何正确附加照片的所有属性和操作?
答案 0 :(得分:3)
看起来你可能会在模型/动作/减速器上划线。与Angular和其他框架不同,你的模型应该是“愚蠢的”,因为它只是数据;您的Gallery
或Photo
对象不应包含方法。相反,您的视图会触发您的reducer用于更新存储(包含模型)的操作,然后将其读取并推回到视图中。与MVVM(MVV *?)不同,您的模型(存储状态)不必模仿组件的结构;相反,它只是维护纯数据。因此,拥有Home
和Gallery
属性可能没有意义。
让我们重新想象您的减速机:
const initialState = {
photos: []
};
export default function reducer(state = initialState, action) {
switch (action.type) {
case 'DELETE_PHOTO':
return {
photos: state.photos.filter(photo => photo.filename !== action.payload.filename)
};
// etc.
}
return state;
}
现在您的观点可能是这样的:
import deletePhoto from '../actionCreators/deletePhoto';
function Photo({ filename, onDelete }) {
return (
<div>
<img src={filename}/>
<button onClick={() => onDelete(filename)}>Delete</button>
</div>
);
}
function PhotoGallery({ photos, deletePhoto }) {
return (
<div>
{
photos.map(photo => <Photo filename={photo.filename} onDelete={deletePhoto}/>);
}
</div>
);
};
const mapStateToProps = state => ({ photos: state.photos });
const mapActionsToProps = { deletePhoto };
export default connect(mapStateToProps, mapActionsToProps)(PhotoGallery);
...然后您的动作创建者deletePhoto
可能类似于:
export default function deletePhoto(filename) {
return { type: 'DELETE_PHOTO', payload: { filename } };
}
建议将缩减器分解为更精细的碎片,但不要通过扩充模型来实现,而是使用combineReducers之类的东西。
我建议你试着忘掉MVVM并真正理解通量模式。我并不是说这是一个更好的模式,但如果你尝试使用不同的模式和redux,那么你真的会反对这种模式。