2016-11-04 309 views
2

我正在學習React,不知道如何解決我的問題。我從Reddit導入數據。我能夠從JSON數據中輸出標題和id,但是當我嘗試對圖像url做同樣的處理時,我得到Uncaught(承諾)TypeError:無法讀取未定義(...)的屬性'圖像'。未捕獲(承諾)TypeError:無法讀取未定義的屬性'圖像'(...)

這是我的代碼(變量filteredPosts是其中所述錯誤發生時)和低於我將包括JSON文件的一部分:

import React from "react"; 
import Projects from "./Projects"; 
import axios from 'axios'; 

export default class MainContainer extends React.Component{ 
    constructor(props){ 
     super(props); 

     this.state = { 
      posts: [] 
     } 

    } 

    componentDidMount(){ 
     axios.get('https://www.reddit.com/r/reactjs.json') 
     .then(res => { 
      const posts = res.data.data.children.map(obj => obj.data); 
      this.setState({posts}); 
     }) 

    } 

    render() { 

     var filteredPosts = this.state.posts.map(post => <Projects key={post.id} title={post.title} imgSrc={post.preview.images[0].source.url}></Projects>); 

     return (
     <div> 
      <div className="container"> 
       <div className="row"> 
        <div className="col-lg-12"> 
         <h1 className="page-header">My Project 
          <small> made with React.js</small> 
         </h1> 
        </div> 
       </div> 
       <div className="row"> 
         {filteredPosts} 
       </div> 
       <hr/> 
       <div className="row text-center"> 
        <div className="col-lg-12"> 
         <ul className="pagination"> 
          <li> 
           <a href="#">&laquo;</a> 
          </li> 
          <li className="active"> 
           <a href="#">1</a> 
          </li> 
          <li> 
           <a href="#">2</a> 
          </li> 
          <li> 
           <a href="#">3</a> 
          </li> 
          <li> 
           <a href="#">4</a> 
          </li> 
          <li> 
           <a href="#">5</a> 
          </li> 
          <li> 
           <a href="#">&raquo;</a> 
          </li> 
         </ul> 
        </div> 
       </div> 
      </div> 
     </div> 
     ); 
    } 
} 

和JSON數據的一部分

{ 
    "kind": "Listing", 
    "data": { 
    "modhash": "", 
    "children": [ 
     { 
     "kind": "t3", 
     "data": { 
      "contest_mode": false, 
      "banned_by": null, 
      "domain": "appendto.com", 
      "subreddit": "reactjs", 
      "selftext_html": null, 
      "selftext": "", 
      "likes": null, 
      "suggested_sort": null, 
      "user_reports": [ 

      ], 
      "secure_media": null, 
      "saved": false, 
      "id": "5b4ly7", 
      "gilded": 0, 
      "secure_media_embed": { 

      }, 
      "clicked": false, 
      "report_reasons": null, 
      "author": "kylebythemile", 
      "media": null, 
      "name": "t3_5b4ly7", 
      "score": 12, 
      "approved_by": null, 
      "over_18": false, 
      "removal_reason": null, 
      "hidden": false, 
      "preview": { 
      "images": [ 
       { 
       "source": { 
        "url": "https:\/\/i.redditmedia.com\/SQmtP8sZ_KVQ7ro86Nxtqbm7pv_9vGRYQasz4WHkcno.jpg?s=666b08d702fd9102b613696796eb024a", 
        "width": 300, 
        "height": 140 
       }, 
       "resolutions": [ 
        { 
        "url": "https:\/\/i.redditmedia.com\/SQmtP8sZ_KVQ7ro86Nxtqbm7pv_9vGRYQasz4WHkcno.jpg?fit=crop&amp;crop=faces%2Centropy&amp;arh=2&amp;w=108&amp;s=8ad5dbf3e11f262813db5ae0abde322b", 
        "width": 108, 
        "height": 50 
        }, 
        { 
        "url": "https:\/\/i.redditmedia.com\/SQmtP8sZ_KVQ7ro86Nxtqbm7pv_9vGRYQasz4WHkcno.jpg?fit=crop&amp;crop=faces%2Centropy&amp;arh=2&amp;w=216&amp;s=35c1ca12d95578caf11c525dc8344197", 
        "width": 216, 
        "height": 100 
        } 
       ], 
       "variants": { 

       }, 
       "id": "6-DU1uRDjVj1MLweYNbxm9T8aMz-XOV8yO5aoKkR1FI" 
       } 
      ] 
      }, 
      "thumbnail": "http:\/\/b.thumbs.redditmedia.com\/mmhbul366OESsJ0BNfSq5rCUsJq74s7R40zzlzwpH6w.jpg", 
      "subreddit_id": "t5_2zldd", 
      "edited": false, 
      "link_flair_css_class": null, 
      "author_flair_css_class": null, 
      "downs": 0, 
      "mod_reports": [ 

      ], 
      "archived": false, 
      "media_embed": { 

      }, 
      "post_hint": "link", 
      "is_self": false, 
      "hide_score": false, 
      "spoiler": false, 
      "permalink": "\/r\/reactjs\/comments\/5b4ly7\/build_a_coffee_finder_app_with_react_native_and\/", 
      "locked": false, 
      "stickied": false, 
      "created": 1478306294, 
      "url": "https:\/\/appendto.com\/2016\/11\/build-a-coffee-finder-app-with-react-native-and-the-yelp-api\/?reddit", 
      "author_flair_text": null, 
      "quarantine": false, 
      "title": "Build a Coffee Finder App with React Native and the Yelp API", 
      "created_utc": 1478277494, 
      "link_flair_text": null, 
      "distinguished": null, 
      "num_comments": 0, 
      "visited": false, 
      "num_reports": null, 
      "ups": 12 
     } 
     }, 

回答

1

問題是,你假設每一個職位將有一個預覽屬性。我做了自己的ajax調用,並在每個帖子上做了一個控制檯日誌,發現至少有6個沒有預覽屬性。

你需要更加防守,並有一個默認圖像或只是空白背景。你可以這樣做:

imgSrc={post.preview ? post.preview.images[0].source.url : defaultImg}

這是假設你有一個defaultImg如果不只是在它的地方返回一個空字符串。

還有一個假設,如果預覽屬性存在,圖像屬性也將存在以及source.url。它總是善於深入研究你正在使用的api,看看它的一致性,不在哪裏以及哪裏不是通過在檢查子屬性之前檢查屬性是否存在來做更多的防禦性編程。

另外,作爲一個最後的選擇,如果你只是想用後的預覽,你可以做一個簡單的過濾器:

this.state.posts.filter((post) => post.preview) // returns only posts with preview property 
相關問題