【发布时间】:2021-01-19 16:00:15
【问题描述】:
我有一个功能组件,它传递了关于从 redux 存储中提取什么的指令。
使用mapStateToProps=(state, ownProps),我可以愉快地从状态(存储)中提取所需的项目 - 但是,整个状态树的任何更改都会触发重新运行 mapStateToProps 和大量重新渲染。
让我打开包装。
这是部分商店的快照:
{
settings: {...stuff...},
projects: [...stuff...],
definitions: [...stuff...],
themes: [...stuff...],
surfaces: {
'6': { <--- VARIABLE PASSED TO COMPONENT
surface: {
STRIP: [..stuff..],
GLOBAL: { <--- CATEGORY PASSED TO COMPONENT
DISPLAY: {...stuff...},
ASSIGNMENT: { <--- LIST OF REQUIRED OBJECTS HAS
A_TRACK: { SUBCATEGORY AND TARGET (A_TRACK etc...)
value: 0,
type: 'switch',
label: 'TRACK'
},
A_SEND: { <--- ANOTHER OBJECT I NEED TO GET
value: 0,
type: 'switch',
label: 'SEND'
},
A_PAN: {
value: 0,
type: 'switch',
label: 'PAN'
},
},
FADER_BANKS: {...stuff...},
STATUS: {...stuff...},
LOTS_MORE_STUFF
我的父组件将所需的指令传递给子组件。
<RefMixerGroup
portId = {this.props.portId}
items={[
{parent: 'GLOBAL', group: "ASSIGNMENT", target: "A_TRACK"},
{parent: 'GLOBAL', group: "ASSIGNMENT", target: "A_SEND"},
]
}
/>
mapStateToProps 非常简单:
const mapStateToPropy = (state, ownProps) => {
return {
groupItems: getItemsFromState(state.surfaces[ownProps.portId].surface, ownProps.items)
}
}
工作是在一个简单的函数中完成的:
const getItemsFromState = (subState, items)=>{
let groupItems=[]
for (let i = 0; i < items.length; i++) {
const item = items[i];
const base = subState[item.parent];
let groupItem = base[item.group][item.target]
groupItems.push({...groupItem, target: item.target})
}
return groupItems
}
但是因为我正在创建这个匹配数组,所以我认为 redux 认为我应该订阅树中的每个项目...当我只想更改找到的元素时,在这种情况下:
surfaces[6].surface[GLOBAL][ASSIGNMENT][A_TRACK]
surfaces[6].surface[GLOBAL][ASSIGNMENT][A_SEND]
我尝试使用 reselect 和 rereselect 而不是上面的 getItemsFromState 函数, 但结果都是一样的。该树中的任何更改(从表面[6] 开始)都会触发 mapsStateToProps 和重新渲染。
一定有办法解决这个问题,但我想不通。我尝试使用areStatesEqual,但它只提供nextState 和prevState,我需要ownProps 来计算相等性。我可能可以使用areStatePropsEqual,但这仅在不必要地重新计算mapStateToProps 之后才有效。
一定有办法!
【问题讨论】:
标签: redux react-redux react-component reselect mapstatetoprops