Обычно вы можете просто go спускаться по предсказанному пути объекта, но поскольку путь объекта может быть переменным из-за природы element
s, я решил использовать комбинацию грубой силы и предсказанного пути объекта.
В этом конкретном сценарии Parent
является общим узлом между всеми element
с, поэтому поиск грубой силы для id
будет работать достаточно хорошо.
Эта функция многократного использования обеспечит грубую силу рекурсивный поиск в узле root для каждого объекта и предоставление обратного вызова для выполнения каждого объекта.
export const iterateNodes = (obj, callback) => {
if (!obj) return undefined
for (let property in obj) {
if (obj.hasOwnProperty(property) && obj[property] != null) {
if (obj[property].constructor === Object) {
iterateNodes(obj[property], callback)
callback(obj[property])
} else if (obj[property].constructor === Array) {
for (let i = 0; i < obj[property].length; i++) {
iterateNodes(obj[property][i], callback)
callback(obj[property][i])
}
} else {
// console.log(obj[property])
}
}
}
return obj
}
Это было извлечено из другого вопроса StackOverflow и немного изменено. Кажется, я не могу найти источник.
Затем вы можете создать другую функцию для изменения узла с определенными параметрами. Этот фрагмент имеет опции overwrite
на случай необходимости перезаписи всего объекта.
export const modifyNodeById = (
root,
id,
modification,
options = {}
) => {
if (!id) throw new Error('id not specified')
return iterateNodes(root, node => {
if (node.id === id) {
if (options.overwrite)
Object.getOwnPropertyNames(node).forEach(key => delete node[key])
Object.assign(node, { ...modification })
}
})
}
Примечание о импорте: эта функция изменяет объект.
Состояние должно изменяться избегать на 100%, поэтому самый простой выход - использовать функцию loda sh cloneDeep
для создания глубокой копии. Вы, вероятно, могли бы оптимизировать копирование только необходимых ветвей в штате, но если ваше состояние не равно cc, оно, вероятно, не стоит.
Таким образом, окончательный ответ может быть:
modifyNodeById(parent, 13, { isUnlocked: true })
Чтобы добавить свойства к узлу объекта с помощью id: 13
, начните поиск в parent
.