2017-11-14 2 views
2

Ich versuche rekursiv JSON-Daten mit React in geschachtelte Liste zu rendern. Im Moment bin ich mit einfachen Datenobjekt wie folgt aus:Verschachtelte React-Liste funktioniert nicht

[{"id": "1", 
"name": "Luke" 
}, 
{"id": "2", 
"name": "Jim", 
    "childNodes":[{ 
    "id": "3", 
    "name": "Lola" 
    }] 
}] 

mit dieser Klasse:

export default class NestedList extends Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     visible: true 
    }; 
    } 

    toggle =() => { 
    this.setState({ visible: !this.state.visible }); 
    }; 

    renderChild = (child) => { 
    if (child.childNodes) { 
     return (
     <ul> 
      {child.myData.map(item => { 
      return this.renderChild(item); 
      })} 
     </ul> 
    ); 
    } 
    else if (child.name) { 
     return <input type="checkbox"><Child name={child.name}/></input>; 
    } 
    return null; 
    } 


    render() { 
    return (
     <aside> 
     <div> 
      <h4>Data Sets</h4> 
      <ul> 
      {this.renderChild(this.props.myData)} 
      </ul> 
     </div> 
     </aside> 
    ); 
    } 
} 

, die eine Kinderklasse aufruft, das Listenelement erstellt:

export default class Child extends Component { 
    render() { 
    let {name}=this.props; 
    return (
     <li>{name}</li> 
    ); 
    } 
} 

aber es doesn‘ t nichts drucken. Ich habe versucht, das Attribut childNodes insgesamt zu entfernen und habe versucht, die Liste zu drucken, aber es funktioniert immer noch nicht. Ich verstehe nicht, wo ich falsch liege. Ich würde etwas Hilfe schätzen, wie man das repariert.

Antwort

0

gab es einige Probleme hier:

  1. Sie haben myData anübergebendie nicht hält childNodes Eigentum noch name Eigentum. Daher wurde keine der Bedingungen erfüllt (Null wurde zurückgegeben).
    Also sollten Sie vielleicht durchlaufen myData und jedes Mitglied des Arrays zu renderChild übergeben.
  2. Auch wenn wir ein gültiges „Kind“ die renderChild Methode, in diesem Zustand übergeben werden:

    if (child.childNodes) { 
    

    Wieder Sie verwenden eine falsche Eigenschaft:

    <ul> 
        {child.myData.map(item => { 
        return this.renderChild(item); 
        })} 
    </ul> 
    

    dies sollte sein:

    {child.childNodes.map(item => {... 
    
  3. Letzte Sache, Sie können chil nicht verschachteln d Elemente in einem input Element. also ändern Sie das Layout, vielleicht so? :

    <input type="checkbox"/> 
        <Child name={child.name} /> 
    

Hier ist ein aktuelles Beispiel mit Ihrem Code:

const data = [ 
 
    { 
 
    id: "1", 
 
    name: "Luke" 
 
    }, 
 
    { 
 
    id: "2", 
 
    name: "Jim", 
 
    childNodes: [ 
 
     { 
 
     id: "3", 
 
     name: "Lola" 
 
     } 
 
    ] 
 
    } 
 
]; 
 

 
class NestedList extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.state = { 
 
     visible: true 
 
    }; 
 
    } 
 

 
    toggle =() => { 
 
    this.setState({ visible: !this.state.visible }); 
 
    }; 
 

 
    renderChild = child => { 
 
    if (child.childNodes) { 
 
     return (
 
     <ul> 
 
      {child.childNodes.map(item => { 
 
      return this.renderChild(item); 
 
      })} 
 
     </ul> 
 
    ); 
 
    } else if (child.name) { 
 
     return (
 
     <div> 
 
      <input type="checkbox"/> 
 
      <Child name={child.name} /> 
 
     </div> 
 
    ); 
 
    } 
 
    return null; 
 
    }; 
 

 
    render() { 
 
    return (
 
     <aside> 
 
     <div> 
 
      <h4>Data Sets</h4> 
 
      <ul>{this.props.myData.map(item => this.renderChild(item))}</ul> 
 
     </div> 
 
     </aside> 
 
    ); 
 
    } 
 
} 
 

 
class Child extends React.Component { 
 
    render() { 
 
    let { name } = this.props; 
 
    return <li>{name}</li>; 
 
    } 
 
} 
 

 
ReactDOM.render(<NestedList myData={data} />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="root"></div>

0

Sie müssen sich durch myData erste abzubilden, so dass die Rendering-Prozess beginnt:

<ul> 
    {this.props.myData.map(data => this.renderChild(data))} 
</ul> 

Auch auf childNodes Sie Schleife müssen durch child.childNodes:

if (child.childNodes) { 
    return (
    <ul> 
     {child.childNodes.map(node => this.renderChild(node))} 
    </ul> 
); 
} 
+0

ich den ersten Ansatz versucht, und ich diesen Fehler: 'Kann nicht Eigentum 'childnodes' lesen von undefined – user8907896

+0

@ user8907896 Also für den zweiten Ansatz gehen :) – mersocarlin

+0

@ user8907896 ist es eigentlich einfacher zu verstehen. – mersocarlin

Verwandte Themen