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.myPosts
i 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 */
lodash
Knjiž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 error
svaki put kad pokušate proslijediti posts
na 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 render
funkcije 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} ); } }