我正在构建一个音频工作站应用程序,它将显示包含剪辑的曲目表。现在我有一个表reducer返回一个表对象。表对象包含轨道对象,轨道对象包含剪辑对象。我有一个TableContainer订阅了表存储。我的问题是我相信我的应用程序效率低下,因为每次添加或操作剪辑时它都会重新呈现页面。实际上,只有剪辑所在的特定轨道需要重新渲染吗?我如何构建我的应用程序,以便不是每一个小的更改都会呈现整个应用程序?
答案 0 :(得分:2)
在任何组件的mapStateToProps
中,不要选择父对象作为整体发送到组件。如果可能,请选择特定属性一直到叶值。如果您的TableContainer
render()
本身没有使用tracks
数组,那么请确保只传递您使用的兄弟属性。
所以而不是:
function mapStateToProps(state, props) {
return {
table: state.tables[props.tableId];
}
}
执行:
function mapStateToProps(state, props) {
let table = state.tables[props.tableId];
return {
name: table.name,
type: table.type
};
这使得React Redux在确定您的组件是否需要重新渲染时更具辨别力。即使table
由于clip
更改而发生了更改,也会看到name
和type
都没有发生变化。
但是,由于您的Table
组件也可能会呈现Track
组件,因此您可能无法避免渲染调用。如果树上任何地方的任何属性都被更改,tracks
数组也会被更改。
在这种情况下,解决方案是让tracks
数组不包含整个track
对象,而只包含一个轨道ID列表。然后,您可以将曲目存储在表格旁边,而一个曲目的变化不会影响另一个曲目。请注意,这仅适用于您未在mapStateToProps
组件的Table
中获取并传递跟踪对象的情况。您应该以这样的方式创建Track
组件,使其接受其ID而不是实际对象作为prop。这样,Table
组件根本不依赖于轨道的内容。
答案 1 :(得分:1)
反应的力量是仅重新呈现需要的东西(通过使用虚拟DOM进行比较和shouldComponentUpdate
功能)。
在它成为性能问题之前,我不会过分关注它。
如果是,我会将曲目存储在一个单独的目录中,而不是将它传递给app(main)组件。在Clip
组件的mapStateToProps
函数中(如果使用react-redux),从道具中获取它的名称时从状态中获取轨道。这样,如果轨道变化很大(例如,由于异步提取切片),只有组件会更新。