动态嵌套的React组件

问题描述 投票:0回答:3

我正在使用下面的代码,它完成了工作(目前)。根据数组的长度,组件彼此嵌套,并使用数组元素引用作为prop。在最里面的元素内部必须始终注入另一个元素。

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 reactjs
3个回答
2
投票

这是我头脑中的一些东西。也许有更好/更清晰的方法来做到这一点,但想法是你遍历数组中的每个项目并向外构建,将每个部分包装在另一个部分内。

为此,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)

0
投票

这是一个递归和声明性的反应组件:

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>} />

0
投票

您可以使用递归渲染方法

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);

Working sandbox

© www.soinside.com 2019 - 2024. All rights reserved.