בטל באמצעות אובייקט מקונן ב- 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.

    זכור כי לשגיאה זו אין שום קשר עם תגובה. זה לא חוקי להעביר אובייקט כילד של רכיב.

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