كرر من خلال كائن متداخل في React.js

إذا سبق لك العمل مع واجهات برمجة التطبيقات ، فستعرف أن بنية البيانات التي يتم إرجاعها يمكن أن تتعقد بسرعة.

تخيل أنك تستدعي 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 }
    ); }

    لكن المشكلة هي أنك لا تستطيع الوصول إلى أي من الأشياء الداخلية.

    ستتغير قيم الكائنات الداخلية دائمًا ، لذلك لن تتمكن من ترميز مفاتيحها بدقة وتكرارها للحصول على القيم المناسبة.

    الحلول الممكنة

    قد يكون من الصعب العمل مباشرة مع استجابات واجهة برمجة التطبيقات المعقدة ، لذلك دعونا نتراجع خطوة إلى الوراء ونبسط:

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