在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/網(wǎng)絡(luò)安全  HTML/ react.createElement如何根據(jù)json遞歸生成dom

react.createElement如何根據(jù)json遞歸生成dom

現(xiàn)在要開發(fā)一個網(wǎng)站,要根據(jù)數(shù)據(jù)庫里保存的節(jié)點ID生成前端頁面,比如:json數(shù)據(jù)為:

let data=[
    {"id":1,"pid":0,"type":"div"},
    {"id":2,"pid":1,"type":"ul"},
    {"id":3,"pid":2,"type":"li"},
    {"id":4,"pid":3,"type":"span"},
    {"id":5,"pid":0,"type":"div"},
    ...
]

一個常規(guī)前端頁面的data結(jié)果應(yīng)該有幾百個數(shù)組元素,pid為父節(jié)點id,如果為頂級節(jié)點(即body標(biāo)簽的直接子節(jié)點),pid=0;

data.map((evt,i)=>{
    React.cteateElement('div',{},[children...]);
})

實際數(shù)據(jù)比這個復(fù)雜,需要判斷節(jié)點類型,是生成div還是ul,span或其他標(biāo)簽,用JSX語法解決不了這個創(chuàng)建問題。因為節(jié)點類型取自data里面的type,有多少層嵌套也是未知的,根據(jù)json結(jié)果而變化。
最后生成的頁面可能是這樣:

<div data-id="1" data-pid="0"></div>
<div data-id="2" data-pid="0">
    <div data-id="3" data-pid="2">
        <ul data-id="5" data-pid="3">
            <li data-id="6" data-pid="5">
                <!--里面更多節(jié)點或直接是文本內(nèi)容-->
            </li>
            <li data-id="7" data-pid="5"></li>
        </ul>
    </div>
    <div data-id="4" data-pid="2"></div>
</div>

如何把一個非頂級節(jié)點插入到children里面,如果一個頂級節(jié)點嵌套有多級子節(jié)點,感覺需要用遞歸,這個遞歸要如何寫在createElement里面,一點頭緒沒有,求大神幫忙。

回答
編輯回答
不歸路

cteateElement 的時候就應(yīng)該把 children 準(zhǔn)備好了
所以應(yīng)該從子到父創(chuàng)建實例

需要2個遞歸

  • 第一個遞歸用來整理 json
  • 第二個用來創(chuàng)建實例

參考下面代碼:

class App extends React.Component {
  constructor() {
    super()
    this.badJson = [
      {id: 1, pid: 0, type: 'div'},
      {id: 2, pid: 1, type: 'ul'},
      {id: 3, pid: 2, type: 'li'},
      {id: 4, pid: 3, type: 'span'},
      {id: 5, pid: 0, type: 'div'}
    ]
  }

  handleJson(val, pid) {
    if (val.pid == pid) {
      const children = this.badJson.map(val2 => this.handleJson(val2, val.id)).filter(x => x)
      if (children.length) val.children = children
      return val
    }
  }

  createNodes({id, pid, children, type}) {
    return React.createElement(
      type || 'div',
      {key: id},
      children ? children.map(val => this.createNodes(val)) : id
    )
  }

  render() {
    // 處理 JSON
    const goodJson = this.badJson.map(val => this.handleJson(val, 0)).filter(x => x)

    return <div>{goodJson.map(val => this.createNodes(val))}</div>
  }
}
2018年2月28日 14:12
編輯回答
刮刮樂

你能說說jsx語法為什么解決不了這個問題呢?
根據(jù)你提供的樣例,第一、二層都是div,第三層是ul,第四層是li。
然后通過map return出來就可以了。都不需要遞歸。

2018年7月4日 16:59