Επανάληψη μέσω ένθετου αντικειμένου στο React.js

Εάν έχετε εργαστεί ποτέ με API, θα γνωρίζετε ότι η δομή των δεδομένων που επιστρέφουν μπορεί να γίνει πολύπλοκη γρήγορα.

Φανταστείτε ότι καλείτε ένα API από το έργο React και η απάντηση μοιάζει με αυτήν:

Object1 { Object2 { propertyIWantToAcess: anotherpropertyIWantToAcess: } }

Έχετε αποθηκεύσει τα δεδομένα στην κατάσταση του στοιχείου σας ως this.state.myPostsκαι μπορείτε να αποκτήσετε πρόσβαση στα στοιχεία του εξωτερικού αντικειμένου με τα εξής:

render() { console.log(this.state.myPosts); const data = this.state.myPosts; const display = Object.keys(data).map((d, key) => { return ( 
  • {data.current_route}
  • ); }); return(
      { display }
    ); }

    Αλλά το πρόβλημα είναι ότι δεν έχετε πρόσβαση σε κανένα από τα εσωτερικά αντικείμενα.

    Οι τιμές των εσωτερικών αντικειμένων θα αλλάζουν πάντα, οπότε δεν μπορείτε να κωδικοποιήσετε τα κλειδιά τους και να επαναλάβετε αυτά για να λάβετε τις κατάλληλες τιμές.

    ΠΙΘΑΝΕΣ ΛΥΣΕΙΣ

    Μπορεί να είναι δύσκολο να εργαστείτε απευθείας με πολύπλοκες απαντήσεις API, οπότε ας κάνουμε ένα βήμα πίσω και να απλοποιήσουμε:

    const visit = (obj, fn) => { const values = Object.values(obj) values.forEach(val => val && typeof val === "object" ? visit(val, fn) : fn(val)) } // Quick test const print = (val) => console.log(val) const person = { name: { first: "John", last: "Doe" }, age: 15, secret: { secret2: { secret3: { val: "I ate your cookie" } } } } visit(person, print) /* Output John Doe 15 I ate your cookie */

    Η lodashβιβλιοθήκη έχει απλές μεθόδους για να επιτύχει το ίδιο πράγμα, αλλά αυτός είναι ένας γρήγορος και βρώμικος τρόπος για να κάνετε το ίδιο πράγμα στη βανίλια JS.

    Αλλά ας πούμε ότι θέλετε να απλοποιήσετε περαιτέρω, κάτι σαν:

    render() { // Logs data console.log(this.state.myPosts); const data = this.state.myPosts; // Stores nested object I want to access in posts variable const posts = data.content; // Successfully logs nested object I want to access console.log(posts); // Error, this will not allow me to pass posts variable to Object.keys const display = Object.keys(posts).map(key => {posts[key]} ) return( {display} ); }

    Αλλά μπορείτε να πάρετε ένα λάθος, TypeError: can't convert undefined to object errorκάθε φορά που προσπαθείτε να περάσετε postsστην Object.keys.

    Λάβετε υπόψη ότι αυτό το σφάλμα δεν έχει καμία σχέση με το React. Είναι παράνομο να περάσετε ένα αντικείμενο ως παιδί ενός στοιχείου.

    Object.keys()επιστρέφει μόνο τα κλειδιά του αντικειμένου που παραδόθηκε ως παράμετρος. Θα πρέπει να το καλέσετε πολλές φορές για να επαναλάβετε όλα τα ένθετα κλειδιά.

    Εάν πρέπει να εμφανίσετε ολόκληρο το ένθετο αντικείμενο, μία επιλογή είναι να χρησιμοποιήσετε μια συνάρτηση για να μετατρέψετε κάθε αντικείμενο σε ένα στοιχείο React και να το περάσετε ως πίνακα:

    let data= [] visit(obj, (val) => { data.push(

    {val}

    ) // wraps any non-object type inside

    }) ... return {data}

    Χρήσιμα πακέτα

    Μια άλλη επιλογή είναι να χρησιμοποιήσετε ένα πακέτο όπως το json-query για να τον βοηθήσετε να επαναλάβει τα ένθετα δεδομένα JSON.

    Ακολουθεί μια τροποποιημένη έκδοση της renderπαραπάνω λειτουργίας χρησιμοποιώντας json-query:

     render() { const utopian = Object.keys(this.state.utopianCash); console.log(this.state.utopianCash); var author = jsonQuery('[*][author]', { data: this.state.utopianCash }).value var title = jsonQuery('[*][title]', { data: this.state.utopianCash }).value var payout = jsonQuery('[*][total_payout_value]', { data: this.state.utopianCash }).value var postLink = jsonQuery('[*][url]', { data: this.state.utopianCash }).value var pendingPayout = jsonQuery('[*][pending_payout_value]', { data: this.state.utopianCash }).value var netVotes = jsonQuery('[*][net_votes]', { data: this.state.utopianCash }).value let display = utopian.map((post, i) => { return ( 

    Author: {author[i]}

    Title: {title[i]}

    Pending Payout: {pendingPayout[i]}

    Votes: {netVotes[i]}

    ); }); return ( {display} ); } }