【问题标题】:Render React component recursively递归渲染 React 组件
【发布时间】:2018-06-14 09:53:06
【问题描述】:

我有一个对象数组,需要像未标记列表一样递归地渲染每个对象:

<ul>
   <li>
   </li>
</ul>

所有数据都像简单的 JSON 一样来自服务器:

{
        "Id": 1,
        "Description": "asd",
        "Src": " ",
        "Lft": 0,
        "Rgt": 9
    },
    {
        "Id": 2,
        "Description": "asd2",
        "Src": " ",
        "Lft": 1,
        "Rgt": 2
    },
    {
        "Id": 3,
        "Description": "asd3",
        "Src": " ",
        "Lft": 3,
        "Rgt": 8
    },
    {
        "Id": 4,
        "Description": "asd4",
        "Src": " ",
        "Lft": 4,
        "Rgt": 5
    },
    {
        "Id": 5,
        "Description": "asd5",
        "Src": " ",
        "Lft": 6,
        "Rgt": 7
    }

我正在使用嵌套集模型进行添加和删除。添加/删除是好的,添加新元素会生成并重新计算正确的键(删除相同的) 另外,我可以只渲染所有项目(在我的情况下是一行)。但目标是使其视图分层。 这是我如何渲染 lft|rgt 的示例(但我使用的是通常的 JS)

为了渲染我使用下一个函数(function renderItems(items)):

    renderItems(items) {
    let node = document.getElementById('root');
    node.innerHTML = '';
    if (items.length) {
        var ul = document.createElement('ul');
        var tree = fetchChildElement(ul);
        node.appendChild(tree);
    }
    function fetchChildElement(container, lft, rgt) {
        items.filter(filterItems); //go through data array
        return container;

        function filterItems(item) {
            if (item.Lft === (lft || 0)) {
                var element = document.createElement('li');
                element.innerHTML = (item.Lft + " | " + item.Rgt);

                //check if element got nested elements, if true - call function again
                if (item.Lft + 1 < item.Rgt) {
                    var childContainer = document.createElement('ul');
                    var child = fetchChildElement(childContainer, item.Lft + 1, item.Rgt - 1);
                    element.appendChild(child);
                }

                //add element to container
                container.appendChild(element);

                //check if next element exists and call function for them
                if (rgt && item.Rgt < rgt) {
                    fetchChildElement(container, item.Rgt + 1, rgt);
                }
            }
        }
    }
}

这是我的组件: Item.js

class Item extends Component {

render() {
    let { item, showModalPlusClicked, deleteItem } = this.props

    return (
        <li className="item">     
                {item.Description &&
                    <div>
                        <img src={item.Src} alt="" />
                        {"Description: " + item.Description}
                        <div className="buttons">
                            <button className="addBtn btn" onClick={(id) => showModalPlusClicked(item)}>+</button>
                            <button className="removeBtn btn" onClick={(id) => deleteItem(item.Id)}>-</button>
                        </div>
                        <p>lKey is {item.Lft} <span>|||| rKey is {item.Rgt}</span></p>
                        <p>______________________</p>
                        <p>id is {item.Id}</p>
                    </div>
                }   
        </li>

    )
}

}

这是我的 ItemList.js 组件,我认为所有递归魔法都应该是:

class ItemList extends Component {
render() {
        let { items, showModalPlusClicked, deleteItem } = this.props
        return ( 
            <div className='items'>
                <ul>
                    {items.map((item) =>
                        <Item
                            key={item.Id}
                            item={item}
                            src={item.Src}
                            desc={item.description}
                            lft={item.lft}
                            rgt={item.rgt}
                            showModalPlusClicked={showModalPlusClicked}
                            deleteItem={deleteItem}
                        />
                    )}
                </ul>
            </div>
        )
    }
}

下面是一个屏幕截图,它如何使用正确样式化的项目(但不是分层)呈现,也使用了 display:inline-block in li.items 以便更好地理解

顺便说一句,要渲染第一张图片上的项目,我只需将 {this.renderItems(items)} 传递给 ItemList 的 render() 方法。

所以,最后我觉得还是把上面所有的词都复述一遍比较好。

  • 我有一个对象数组 ItemsList。
  • ItemList 中的每个对象都是 Item。
  • 每个项目都有 2 个主要标识符(leftKey - lft 和 rightKey - rgt),它们应该用于在无序列表 () 中显示项目。
  • 我得到了 javascript 函数,它可以获取此键并在 index.html 中显示 smth,但我不明白如何重新制作它(或者可能函数应该完全是另一个)
  • 另外,我将不同的数据传递到我的 JS 函数中,它使 ul>li 正确,所以我真的认为所有更改都应该在其中。
因此,我无法以这种方式呈现我的反应组件 Item 的主要问题。

编辑 “那样”我的意思是 - 项目组件呈现为无序列表(参见第一张图片)。我该图像只有左右键,而不是它们应该有整个 Item 组件(如图像 2 上)

编辑 任何想法如何实现这一点?我绝望了……

【问题讨论】:

  • 输出应该是什么?喜欢在第一个屏幕上?
  • 是的,输出应该像在第一个屏幕上一样,但不仅仅是左右键(就像我的情况一样)。应该是反应组件Item。

标签: javascript reactjs recursion react-redux nested-sets


【解决方案1】:

我在开发多线程聊天应用程序时遇到了同样的问题。 Demo

我设计了组件的 css,这样当一个新组件渲染时,它会稍微移动以实现您正在寻找的内容。 React Code

希望这会有所帮助。

【讨论】:

  • 感谢您的解决方案,但不幸的是,这并不是真正需要的。仍然尝试递归地渲染我的组件,现在我想我需要了解如何将组件包装在
    • 中,然后将整个列表添加到 html。调试了我的 js 函数,它没问题,但正确 wrappin 的问题仍然存在。
猜你喜欢
  • 2019-12-21
  • 2021-03-10
  • 2019-12-10
  • 2020-12-22
  • 2020-09-08
  • 2020-12-12
  • 2018-05-11
  • 1970-01-01
相关资源
最近更新 更多