Я использую приведенный ниже код, и он выполняет свою работу (на данный момент). В зависимости от длины массива компоненты вкладываются друг в друга со ссылкой на элемент массива в качестве опоры. Внутри самого внутреннего элемента всегда должен быть вставлен другой элемент.
const arr = ['one', 'two', 'three'];
const injectedContent = <SomeContent />;
const renderNestedSections = () => {
switch (arr.length) {
case 1:
return (
<Section name = {arr[0]}>
{injectedContent}
<Section>
);
case 2:
return (
<Section name = {arr[0]}>
<Section name = {arr[1]}>
{injectedContent}
</Section>
</Section>
);
case 3:
return (
<Section name = {arr[0]}>
<Section name = {arr[1]}>
<Section name = {arr[2]}>
{injectedContent}
</Section>
</Section>
</Section>
);
default:
return null;
}
}
Я изо всех сил пытаюсь создать функцию с алгоритмом, который динамически выполняет вложение. Любая помощь будет высоко ценится. Заранее спасибо.



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


Вот что-то не в моей голове. Возможно, есть лучший / более ясный способ сделать это, но идея состоит в том, что вы перебираете каждый элемент в массиве и строите его наружу, оборачивая каждый раздел внутри другого раздела.
Для этого используется Array#reduce, начиная со значения аккумулятора вашего внедренного контента. Затем вы просто строите вверх по направлению к самой внешней секции. Кроме того, поскольку мы строим наружу, а не внутрь, мы должны перевернуть массив (имейте в виду, что это приведет к изменению массива, поэтому вы можете захотеть клонировать его, прежде чем делать это).
Вот доказательство концепции с использованием DOM, а не React.
let arr = ['one', 'two', 'three']
// Inner Content
let content = document.createElement('div')
content.innerHTML = "Hello World"
// Algorithm
let res = arr.reverse().reduce((acc, item)=>{
let a = document.createElement('div')
a.classList.add(item)
a.appendChild(acc)
return a
}, content)
document.body.appendChild(res)div {
padding : 10px;
color : white;
}
.one {
background-color: red;
}
.two {
background-color: green;
}
.three {
background-color: blue;
}Вот как, я думаю, будет выглядеть версия React, но я ее не тестировал.
const arr = ['one', 'two', 'three'];
const injectedContent = <SomeContent />;
// Algorithm
let result = arr.reverse().reduce((acc, item)=>{
return (
<Section name = {item}>
{acc}
</Section>
)
}, InjectedContent)
Вы можете использовать рекурсивный подход к рендерингу, например
const arr = ["one", "two", "three", "four"];
const injectedContent = () => <SomeContent />;
const Section = ({ name, children }) => (
<div>
<div>{name}</div>
{children}
</div>
);
const SomeContent = () => <div>Some Content</div>;
const RecursiveContent = ({ InjectedContent, arr }) => {
const name = arr[0];
return (
<Section arr = {arr} name = {name}>
{arr.length > 0 ? (
<RecursiveContent arr = {arr.slice(1)} InjectedContent = {InjectedContent} />
) : (
<InjectedContent />
)}
</Section>
);
};
const NestedSection = InjectedContent => ({ arr }) => (
<RecursiveContent arr = {arr} InjectedContent = {InjectedContent} />
);
function App() {
return (
<div className = "App">
<NestedEle arr = {arr} />
</div>
);
}
const NestedEle = NestedSection(injectedContent);
это компонент реакции рекурсивный и декларативный:
const RecursiveNodeWrapper = ({ layers, node }) => {
let accumulatedNode = node;
if (layers.length) {
const [currentLayer, ...restLayers] = layers;
accumulatedNode = (
<section style = {{ border: '1px solid', padding: 5 }} name = {currentLayer}>
{accumulatedNode}
</section>
);
return RecursiveNodeWrapper({
layers: restLayers,
node: accumulatedNode,
});
}
return accumulatedNode;
};
тогда вам просто нужно вызвать его как обычный компонент:
<RecursiveNodeWrapper layers = {['one', 'two']} node = {<h1>hello</h1>} />
Я протестировал его, и он отлично работает. Очень компактное решение, еще раз спасибо!