Итерација кроз угнежђени објекат у Реацт.јс-у

Ако сте икада радили са АПИ-има, знаћете да се структура података које враћају може брзо закомпликовати.

Замислите да позовете АПИ из вашег Реацт пројекта и одговор изгледа отприлике овако:

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

    Али проблем је што не можете да приступите ниједном унутрашњем објекту.

    Вредности унутрашњих објеката ће се увек мењати, тако да нећете моћи да кодирате њихове кључеве и прелиставате их да бисте добили одговарајуће вредности.

    Могућа решења

    Може бити тешко директно радити са сложеним АПИ одговорима, зато вратимо се корак уназад и поједноставимо:

    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Библиотека има једноставне методе да се постигне исту ствар, али ово је брзо и прљаво начин да се уради исту ствар у ваниле ЈС.

    Али реците да желите да поједноставите, отприлике као:

    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.

    Имајте на уму да ова грешка нема никакве везе са Реацт-ом. Противзаконито је преношење предмета као дете компоненте.

    Object.keys()враћа само кључеве објекта који је прослеђен као параметар. Мораћете да га позовете више пута да бисте прегледали све угнежђене кључеве.

    Ако требате приказати цео угнежђени објекат, једна опција је употреба функције за претварање сваког објекта у Реацт компоненту и прослеђивање као низ:

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

    {val}

    ) // wraps any non-object type inside

    }) ... return {data}

    Корисни пакети

    Друга опција је употреба пакета попут јсон-куери за помоћ у итерацији угнежђених ЈСОН података.

    Ево модификоване верзије 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} ); } }