В последнее время я пишу приложения response-redux, и как разработчик React я пишу чистый, функциональный и предсказуемый код. Несмотря на то, что мне нравится этот опыт, я сомневаюсь, красив ли мой код или нет.
Итак, у меня есть дерево в моем состоянии, и мне нужно обновить кучу узлов в дереве. Допустим, API дерева предоставляет метод pureUpdate(path, newNode, tree) => newTreeчистый, который возвращает новое дерево с обновленным узлом. В этом случае мой метод редуктора может выглядеть как
function updateNodes(tree, updateRules) {
updateRules.forEach(updateRule => {
const { path, node } = updateRule;
tree = pureUpdate(path, node, tree);
});
return tree;
}
Но я не уверен, что можно было бы сделать лучшее.
Первое, что выглядит неприятно, - это tree = pureUpdate(path, node, tree);. Похоже на изменение параметра, что не рекомендуется, но я просто переназначаю
ссылка, не так ли? Это объясняется здесь во второй части ответа. Но хотя этот трюк может быть приемлемым, в этом обсуждении сказал, что такой код может быть неоптимизированным, и переназначение параметров может вызвать проблемы с производительностью (больше информации с примерами). Самое простое исправление, которое пришло мне на ум, - использовать дополнительную переменную, которая будет клоном дерева.
function updateNodes(tree, updateRules) {
let newTree = someCloneFunc(tree);
updateRules.forEach(updateRule => {
const { path, node } = updateRule;
newTree = pureUpdate(path, node, newTree);
});
return newTree;
}
Вопрос в том, ничего ли я не пропускаю, а мой код остается чистым, красивым и не вызовет никаких проблем.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если вас вообще беспокоит производительность, я бы не стал клонировать tree только для того, чтобы не переназначать параметр.
Хотя здесь вы можете использовать forEach и переназначить параметр, reduce - это правильная функциональная абстракция для вашего варианта использования, и, как правило, это лучшая и более полезная абстракция, чем forEach, поскольку ее можно (и нужно) использовать в чистом виде, тогда как forEach всегда на стороне. последствия.
Решение, основанное на reduce, также делает вопрос о том, следует ли клонировать и / или переназначать параметр функции, полностью спорным.
Вот рабочее решение для reduce - без переназначения параметров, без побочных эффектов forEach и без причин для клонирования tree:
const updateNodes = (tree, updateRules) =>
updateRules.reduce(
(acc, { path, node }) => pureUpdate(path, node, acc),
tree // initialize acc (the accumulator)
)
Если вы хотите заниматься чисто функциональным программированием, никогда используйте
forEach.