【问题标题】:Create JSX tree from flat Array with recursive function in react在反应中使用递归函数从平面数组创建 JSX 树
【发布时间】:2020-09-16 19:25:32
【问题描述】:

我真的需要你的帮助来使用递归函数从平面数组中创建 JSX 树。

目前只有1到6项正确显示,之后递归停止

1) 我的平面 JSON 数据是:(但它可能有 1000 多个项目)

const itemsData = [
{
  "Level": 1,
  "Type of activity": "Consolidated task",
  "ID": 118027222233,
  "Name": "Name 1"
},
{
  "Level": 2,
  "Type of activity": "Consolidated task",
  "ID": 118636886633,
  "Name": "Name 2"
},
{
  "Level": 3,
  "Type of activity": "Consolidated task",
  "ID": 118637048333,
  "Name": "Name 3"
},
{
  "Level": 4,
  "Type of activity": "task",
  "ID": 118637035433,
  "Name": "Name 4"
},
{
  "Level": 4,
  "Type of activity": "task",
  "ID": 118841127933,
  "Name": "Name 5"
},
{
  "Level": 4,
  "Type of activity": "task",
  "ID": 118841156833,
  "Name": "Name 6"
},
{
  "Level": 3,
  "Type of activity": "Consolidated task",
  "ID": 118637046733,
  "Name": "Name 9"
},
{
  "Level": 4,
  "Type of activity": "Consolidated task",
  "ID": 118744514633,
  "Name": "Name 10"
},
{
  "Level": 5,
  "Type of activity": "task",
  "ID": 118637033033,
  "Name": "Name 11"
},
{
  "Level": 5,
  "Type of activity": "task",
  "ID": 118637031033,
  "Name": "Name 13"
},
{
  "Level": 2,
  "Type of activity": "Consolidated task",
  "ID": 118636886633,
  "Name": "Name 19"
},
{
  "Level": 3,
  "Type of activity": "task",
  "ID": 118637048333,
  "Name": "Name 20"
},
{
  "Level": 3,
  "Type of activity": "task",
  "ID": 118637048333,
  "Name": "Name 21"
}]

2) 我当前的递归函数如下所示: 但只有项目 1 到 6 正确显示。

const RecursiveFunction = ({currentItem, currentLevel}) => {

//LOOP  AS LONG AS CURRENTITEM < ITEMS DATA LENGTH 
while(currentItem < itemsData.length){

    //IF CONSOLODATED TASK CREATE CONTAINER
    if(itemsData[currentItem]["Type of activity"] === "Consolidated task"){


        //TEST IF CHILD RELATED TO LEVEL
        if(currentLevel < itemsData[currentItem].Level ){


            //LINE COUNTER
            currentItem++;

            //RETURN
            return (
                <div className="conso-container">
                    <div className="conso-title">
                        {itemsData[currentItem - 1].Name}
                    </div>
                    <RecursiveFunction currentItem={currentItem} currentLevel={itemsData[currentItem-1].Level} />
                </div>
            )
        }

    }else{

        //CURRENT TASK LIST ON A BLOCK
        let taskList = [];

        //WHILE IS A TASK
        while(currentItem < itemsData.length && itemsData[currentItem]["Type of activity"] !== "Consolidated task"){

            //LIST ALL THE TASK
            taskList.push(<div className="task-title">{itemsData[currentItem].Name}</div>)
            currentItem++;

        }

        // RETURN    
        return (
            <div className="task-container">
                {taskList}
            </div>
        )
    }
}}

3)我的渲染是

class RoadMapItems extends React.Component {


render(){
    return( 
        <div className="tree">
            <RecursiveFunction currentItem={0} currentLevel={0} />
        </div>
    )
}}export default RoadMapItems;

【问题讨论】:

  • 真正的问题是什么? :)
  • 实际上没有任何效果...我链接了两张图片以向您展示我的目标是什么。但我不知道我的策略是否正确
  • @julienlaurent 问题是你将items 作为一个完整的数组再次传递,这意味着它第一次传递了 10 个项目,而第一次递归你又传递了 10 个项目,所以它会无限循环
  • 既然有flatList,为什么还要有递归函数
  • 数组总是有序的吗?如果您在孩子上有一个 parentID 字段可能会有所帮助,但如果他们总是正确排序,我想这可以即时完成。 @ShubhamKhatri 是正确的,使用平面表示,您不需要递归,如果您将平面转换为嵌套(parentID 会有所帮助)或者如果您的初始数据是嵌套的,那么您将需要递归。

标签: javascript arrays reactjs recursion jsx


【解决方案1】:

这应该可以。比我最初想象的要难一点,哈哈。 ?

您确实需要转换为嵌套数据结构,然后递归地映射它以提供所需的输出:

以下和此处的完整演示:https://codepen.io/Alexander9111/pen/pojXBWX

function MyTable(props) {
  const initState = [
    {
      Level: 1,
      "Type of activity": "Consolidated task",
      ID: 118027222233,
      Name: "Name 1"
    },
    {
      Level: 2,
      "Type of activity": "Consolidated task",
      ID: 118636886633,
      Name: "Name 2"
    },
    {
      Level: 3,
      "Type of activity": "Consolidated task",
      ID: 118637048333,
      Name: "Name 3"
    },
    {
      Level: 4,
      "Type of activity": "task",
      ID: 118637035433,
      Name: "Name 4"
    },
    {
      Level: 4,
      "Type of activity": "task",
      ID: 118841127933,
      Name: "Name 5"
    },
    {
      Level: 4,
      "Type of activity": "task",
      ID: 118841156833,
      Name: "Name 6"
    },
    {
      Level: 3,
      "Type of activity": "Consolidated task",
      ID: 118637046733,
      Name: "Name 9"
    },
    {
      Level: 4,
      "Type of activity": "Consolidated task",
      ID: 118744514633,
      Name: "Name 10"
    },
    {
      Level: 5,
      "Type of activity": "task",
      ID: 118637033033,
      Name: "Name 11"
    },
    {
      Level: 5,
      "Type of activity": "task",
      ID: 118637031033,
      Name: "Name 13"
    },
    {
      Level: 2,
      "Type of activity": "Consolidated task",
      ID: 118636886633,
      Name: "Name 19"
    },
    {
      Level: 3,
      "Type of activity": "task",
      ID: 118637048333,
      Name: "Name 20"
    },
    {
      Level: 3,
      "Type of activity": "task",
      ID: 118637048333,
      Name: "Name 21"
    },
    {
      Level: 2,
      "Type of activity": "Consolidated task",
      ID: 128637048333,
      Name: "Name 22"
    },
    {
      Level: 3,
      "Type of activity": "task",
      ID: 138637048333,
      Name: "Name 23"
    },
    {
      Level: 1,
      "Type of activity": "Consolidated task",
      ID: 148637048333,
      Name: "Name 24"
    },
    {
      Level: 2,
      "Type of activity": "task",
      ID: 158637048333,
      Name: "Name 25"
    }
  ];
  const [state, setState] = React.useState(initState);

  const table = (
    <table>
      <tr key={"header"}>
        {Object.keys(state[0]).map((key) => (
          <th>{key}</th>
        ))}
      </tr>
      {state.map((item) => (
        <tr key={item.id}>
          {Object.values(item).map((val) => (
            <td>{val}</td>
          ))}
        </tr>
      ))}
    </table>
  );

  let currPointer = null;
  const listOfPointers = [];
  const nestedArrs = state.reduce((aggArr, item) => {
    //console.log(listOfPointers)
    if (item.Level == 1) {
      aggArr.push(item);
    }
    else if (item.Level > currPointer.Level) {
      currPointer.children.push(item);
    }
    else if (item.Level <= currPointer.Level) {
      while (item.Level <= currPointer.Level) {
        listOfPointers.pop();
        currPointer = listOfPointers[listOfPointers.length - 1];
      }
      currPointer.children.push(item);
    }
    
    item.children = [];
    currPointer = item;
    listOfPointers.push(currPointer);

    return aggArr;
  }, []);

  //console.log(nestedArrs);

  const nestedDivs = (
    <div>
      {(function mapChildren(data) {
        return data.map((d, i) => {
          if (d["Type of activity"] != "task") {
            return (
              <div className={"level_" + d.Level}>
                <span>{d.Level + " : " + d.Name}</span>
                {mapChildren(d.children)}
              </div>
            );
          } else {
            return (
              <div className={"level_" + d.Level + " task"}>
                <span>{d.Level + " : " + d.Name}</span>
              </div>
            );
          }
        });
      })(nestedArrs)}
    </div>
  );
  //console.log(nestedDivs);

  return (
    <div>
      {table}
      {nestedDivs}
    </div>
  );
}

ReactDOM.render(<MyTable />, document.getElementById("target"));
th,
td {
  border: 1px solid black;
  margin: 0px 0px;
  padding: 5px 5px;
}
div {
  padding: 10px;
  margin: 10px;
}
.level_1 {
  background-color: blue;
}
.level_2 {
  background-color: orange;
}
.level_3 {
  background-color: green;
}
.level_4 {
  background-color: yellow;
}
.task {
  background-color: white !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="target"></div>

输入:

输出:

【讨论】:

  • 非常感谢@AlexL!完美传递给嵌套数据。递归函数非常好,正是我要找的!这是我的第一个 javascript 函数之一,目前它对我来说有点复杂,但你的例子看起来很清楚!再次感谢
  • 很高兴听到我的答案很明确?而且很有帮助?递归会很快变得复杂和混乱,但稍微练习一下,它会非常强大!祝你好运!
猜你喜欢
  • 2013-09-28
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 2017-02-13
  • 2021-04-18
  • 1970-01-01
相关资源
最近更新 更多