React.js:在渲染之前从嵌套的JSON动态创建复杂的DOM

时间:2018-03-19 06:03:18

标签: javascript json reactjs

最近我试图解决一个问题,我必须从来自请求调用的嵌套JSON渲染文档树菜单(层次结构)。

说我的JSON看起来像这样

[{
    "title": "Food",
    "path": "/root",
    "children": [{
        "title": "Veg",
        "path": "/root/Food",
        "children": [{
            "title": "Carrot",
            "path": "/root/Food/Veg",
            "children": [{
                "title": "Ooty carrot",
                "path": "/root/Food/Veg/Brinjal",
                "children": []
            }]
        }]
    }]
}, {
    "title": "Cloths",
    "path": "/root",
    "children": [{
        "title": "T shirt",
        "path": "/root/Cloths",
        "children": []
    }, {
        "title": "Shirt",
        "path": "/root/Cloths",
        "children": []
    }]
}]

我必须从上面的JSON

创建以下DOM

enter image description here

通过jQuery解决:

我已准备好将JSON转换为DOM的函数:在普通的jQuery中我会做类似以下的事情:

$(function(){
    function get_tree(tree_data){
      dom += '<ul>';
      for(var i in tree_data){
        if(tree_data[i].children.length > 0){
          dom += '<li>';
          dom += '<a href="#" class="tree-parent-anchor">'+tree_data[i].title+'</a>';
          get_tree(tree_data[i].children);
          dom += '<li>';
        }
        else{
          dom += '<li>'+tree_data[i].title+'</li>'
        }
      }
      dom+= '</ul>'
    }
    var tree_data = JSON.parse($('pre').text());
    var dom= '<ul id="Menu-list">';
            get_tree(tree_data);
        dom+= '</ul>'
    $('div').append(dom);
})

在REACT.JS中我尝试了这个(ofcrse它不起作用):

export default class DocTree extends Component{
    state = {treeData: [{
            "title": "Food",
            "path": "/root",
            "children": [{
                "title": "Veg",
                "path": "/root/Food",
                "children": [{
                    "title": "Carrot",
                    "path": "/root/Food/Veg",
                    "children": [{
                        "title": "Ooty carrot",
                        "path": "/root/Food/Veg/Brinjal",
                        "children": []
                    }]
                }]
            }]
        }, ...
        }]
    }

    render(){
        const tree_data = this.state.treeData;
        function get_tree(tree_data, dom){
              <ul>
                for(var i in tree_data)
                    if(tree_data[i].children.length > 0)
                        <li>
                            <a href="#" className="tree-parent-anchor">{tree_data[i].title}</a>
                            get_tree(tree_data[i].children);
                        <li>

                    else
                        <li>{tree_data[i].title}</li>
                </ul>

        var dom = <ul id="Menu-list">
            get_tree(tree_data);
        </ul>

        return(
            <div>
                {dom}
            </div>
        );
    }
}

我不知道如何通过React.js语法

实现相同目的
  

请帮助我 - 如何在React.js (使用React.js 16.2.0)

2 个答案:

答案 0 :(得分:2)

你不能在JSX中使用for循环,其次你可以在映射每个对象后递归渲染你的树

&#13;
&#13;
const data =[{
    "title": "Food",
    "path": "/root",
    "children": [{
        "title": "Veg",
        "path": "/root/Food",
        "children": [{
            "title": "Carrot",
            "path": "/root/Food/Veg",
            "children": [{
                "title": "Ooty carrot",
                "path": "/root/Food/Veg/Brinjal",
                "children": []
            }]
        }]
    }]
}, {
    "title": "Cloths",
    "path": "/root",
    "children": [{
        "title": "T shirt",
        "path": "/root/Cloths",
        "children": []
    }, {
        "title": "Shirt",
        "path": "/root/Cloths",
        "children": []
    }]
}]


const MyComponent = ({data}) => {
   return (
    <ul>
      {data.map((m, index) => {
        return (<li key={index}>
          {m.title}
          {m.children && <MyComponent data={m.children} />}
        </li>);
      })}
    </ul>
  );
}
class App extends React.Component {

  
  render() {
     return <div>
        <MyComponent data={data} />
     </div>
  }
}

ReactDOM.render(<App/>, document.getElementById('root'));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="root"/>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

你误解了JSX。

让我们将其视为服务器端语言(例如:PHP,ASP),

您正在做的是embed HTML and JSX,就像embed HTML and PHP一样。

<强>为什么吗 JSX是js,JSX元素是引擎盖下的一个对象。

你可以在https://babeljs.io/repl/上运行一些hello world JSX,看看JSX是如何转换成ES5的(如果是ES5浏览器),你就会理解JSX。

有关详细信息,请阅读React基础知识,尤其是JSX in depth

最后,这是需要进行的修改:

function get_tree(tree_data, dom){
  var elems = [];

  for(var i in tree_data)
    if(tree_data[i].children.length > 0)
      elems.push(<li>
          <a href="#" className="tree-parent-anchor">{tree_data[i].title}</a>
          {get_tree(tree_data[i].children)}
          </li>)
    else
      elems.push(<li>{tree_data[i].title}</li>)

  return <ul>{elems}</ul>
}

顺便说一下,你的代码在实践中很糟糕,因为你是React的新手,你应该考虑@Shubham Khatri的想法并遵循他的做法。