React Redux访问mapStateToProps中的动态过滤状态-重新渲染问题



我有一个功能组件,它传递了从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]

我尝试使用重新选择和重新选择,而不是上面的getItemsFromState函数,但是所有的结果都是相同的。该树中的任何更改,从曲面[6]开始,都会触发mapsStateToProps和重新渲染器。

这肯定有办法,但我想不通。我尝试使用areStatesEqual,但它只提供nextStateprevState,并且我需要ownProps来计算相等。我可能会使用areStatePropsEqual,但只有在不必要地重新计算mapStateToProps之后才能使用。

一定有办法!

getItemsFromState每次运行时都会创建一个新的groupItems数组引用。它将在每个调度的操作之后调用。由于connectmapState返回的任何字段更改为新引用时都会重新渲染,因此您的代码每次都会强制React Redux重新渲染。

这就是为什么您应该使用内存化选择器,仅在输入引用发生更改时才返回新的派生数据引用,通常使用Reselect的createSelector。如果你使用Reselect在这里没有帮助,很可能是你的选择器设置不正确,但我需要看看具体的例子来给出建议。

这也是组件应该订阅他们实际需要的最小数据量的原因。

如果您使用的是函数组件,我建议您也使用useSelector而不是connect

相关内容

  • 没有找到相关文章

最新更新