如何以递归方式呈现React Component

时间:2017-09-01 15:22:18

标签: reactjs react-redux

我有一个组件说,List Component。列表组件可以呈现项目 通过组件ListItem。这可以通过下面的内容轻松实现

import React from 'react';
import ListItem from '../list-item/list-item';

class List extends React.Component {

  renderListItems() {
    return this.props.items.map(item => <ListItem item={item} />)
  }

  render(){
    return (
      <div className="list">{this.renderListItems()}</div>
    )
  }

}

import React from 'react';
class ListItem extends React.Component {

  render(){
    return (
      <div className="list-item">Name: {this.props.item.name}</div>
    )
  }

}

现在,在这种情况下,如果列表项可以在其中包含父子项,即一个列表项可以进一步呈现更多列表项,我如何从其自身内呈现ListItem组件。以下是我正在寻找的渲染树以及我的数据状态

List
 - ListItem
  - ListItem
  - ListItem
 - ListItem
 - ListItem

修改

我认为正确的结构将是这样的

List
 - ListItem
  - List
    - ListItem
    - ListItem
 - ListItem
 - ListItem

但它会在List和ListItem组件之间创建一个循环依赖,这会有问题吗?

4 个答案:

答案 0 :(得分:9)

您应该将渲染逻辑抽象为一个单独的方法,您可以从“render”方法中递归调用该方法:

{{item.description | limitTo: 10}}

完全未经测试的代码,但它应该提供这个想法。

答案 1 :(得分:0)

使用功能组件:

//List.js
import React from 'react';

import ListItem from '../your_path/ListItem';

export default function List({items}) {
  return(
    <div className="list">
    {
      items.map(item => {
        if(item.name){
          return <ListItem item={item} />
        }
        return <List items={item} /> 
      })
    }
    </div>
  );
}


//ListItem.js: 
import React from 'react';
export default function ListItem({item}){
  return (
    <div className="list-item">Name: {item.name}</div>
  )
}

没有测试,但是我认为这应该起作用。

答案 2 :(得分:0)

经过测试。 确实在组件的渲染器中递归调用了它。

import React from "react";
import { isItemComponent } from "../utils/utils";

const SubMenuModified = ({
      SubMenuComponent,
      ItemComponent,
      data,
      ...others
    }) => {
      return (
        <SubMenuComponent
          key={`SubMenuComponent${data.id}`}
          title={<span>{data.name}</span>}
          {...others}
        >
          {data.list.map(info => {
            if (isItemComponent(info)) {
              return <ItemComponent key={info.id}>{info.name}</ItemComponent>;
            } else {
              return (
                <SubMenuModified
                  SubMenuComponent={SubMenuComponent}
                  ItemComponent={ItemComponent}
                  key={`SubMenuComponent${info.id}`}
                  data={info}
                  {...others}
                />
              );
            }
          })}
        </SubMenuComponent>
      );
    };

    export default SubMenuModified;

答案 3 :(得分:-2)

以这种方式递归更干净

const Asterics= ({i}) => [
  <b>*</b>,
  i>0 && <RAsterics i={i-1}/>
]
const RAsterics = (props)=><Asterics {...props}/>

export default Asterics