Ponavljajte kroz ugniježđeni objekt u React.js-u

Ako ste ikad radili s API-ima, znat ćete da se struktura podataka koje vraćaju može brzo zakomplicirati.

Zamislite da iz svog React projekta nazovete API i odgovor izgleda otprilike ovako:

Object1 { Object2 { propertyIWantToAcess: anotherpropertyIWantToAcess: } }

Pohranili ste podatke u stanju svoje komponente kao this.state.myPostsi možete pristupiti elementima vanjskog objekta na sljedeći način:

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 }
    ); }

    Ali problem je što ne možete pristupiti niti jednom unutarnjem objektu.

    Vrijednosti unutarnjih objekata uvijek će se mijenjati, tako da ne možete tvrdo kodirati njihove ključeve i prelistavati ih da biste dobili odgovarajuće vrijednosti.

    Moguća rješenja

    Može biti teško izravno raditi sa složenim API odgovorima, pa vratimo se korak unatrag i pojednostavimo:

    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 */

    lodashKnjižnica ima jednostavne metode kako bi ostvarili istu stvar, ali to je brz i prljav način učiniti istu stvar u vanilije JS.

    Ali recite da želite dodatno pojednostaviti, otprilike kao:

    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} ); }

    Ali dobit ćete pogrešku TypeError: can't convert undefined to object errorsvaki put kad pokušate proslijediti postsna Object.keys.

    Imajte na umu da ova pogreška nema nikakve veze s Reactom. Protuzakonito je dodavanje predmeta kao podređenog dijela komponente.

    Object.keys()vraća samo ključeve objekta koji je proslijeđen kao parametar. Morat ćete ga nazvati više puta da biste pregledali sve ugniježđene ključeve.

    Ako trebate prikazati cijeli ugniježđeni objekt, jedna je opcija upotreba funkcije za pretvaranje svakog objekta u komponentu React i prosljeđivanje kao niz:

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

    {val}

    ) // wraps any non-object type inside

    }) ... return {data}

    Korisni paketi

    Druga je mogućnost upotreba paketa poput json-upita za pomoć u iteraciji ugniježđenih JSON podataka.

    Evo izmijenjene verzije renderfunkcije iznad pomoću 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} ); } }