У меня есть функциональный компонент, которому передаются инструкции о том, что вытащить из хранилища 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], запускает mapStateToProps и повторную визуализацию.
Должен быть способ обойти это, но я не могу этого понять. Я пробовал использовать areStatesEqual
, но он предоставляет только nextState
и prevState
, а мне нужно ownProps
для вычисления равенства. Возможно, я мог бы использовать areStatePropsEqual
, но это работает только ПОСЛЕ перерасчета mapStateToProps
без необходимости.
Должен быть способ!