2016-05-18 22 views
0

我正在製作一個應用程序,該應用程序應該在某個時間點獲取帶有標題,說明和用戶信息的信息源。我在原生反應中這樣做,這些也是同一視圖中的兩個單獨的提要,它們可以在兩個選項卡之間切換,所以我認爲我目前的架構隨後會是最佳的。組件生命週期中的問題/無法處理undefined

手頭的問題:

從Methods.js:

exports.getFriendFeed = function(TOKEN) { 
    return new Promise((resolve, reject) => { 
     fetch(baseUrl + 'feed' , { 
     method: 'GET', 
     headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'application/json', 
     'Token' : TOKEN, 
     }, 
    }) 
    .then((response) => response.text()) 
    .then((responseText) => { 

     resolve(responseText); 
    }) 
    .catch((error) => { 
     reject(error); 
    }); 
    }); 
}; 

我寫的讀取請求,並將其發送到我的home.js屏幕。而如下處理它:

var Home = React.createClass({ 
. 
. 
. 
    changeComponent: function(component) { 
    Method.getFriendFeed(this.state.tokenSupreme) 
    .then((res) => this.setState({ 
     friendFeed: JSON.parse(res).friendPosts, 
     loaded: true, 
    })) 
    .catch((error) => console.log(error)) 
    .done();  
    this.setState({ 
     componentSelected: component, 
    }) 
    }, 

也就是說當我按到一定饋查看內容專門加載該視圖。

渲染的成分並且透過所述信息流的道具和它是否被裝入:

renderComponent: function(component) { 
     if(component === 'One') { 
     return <ComponentOne 
     friendData={ 
      this.state.friendFeed 
     } 
     loaded={ 
      this.state.loaded 
     } /> 
     } else if(component === 'Two') { 
     return <ComponentTwo /> 
     } 
    }, 

但現在來了真正的問題。遵循React Native提供的文檔。我有console.log編輯rowData產生「加載」,然後它返回我想要的json格式數據。所以這意味着它首先成功地通過了changeComponent函數並且變成了「加載」,並且錯誤地將this.state.loaded變爲true,這意味着然而在這個執行過程中有一個時間點我不能調用任何特定的鍵或名字我的JSON由於它只有「種類」加載的事實,它只是返回未定義,紅色立即屏幕應用程序。

var ComponentOne = React.createClass({ 
    getInitialState: function() { 
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    return { 
     dataSource: ds.cloneWithRows(this.props.friendData), 
    }; 
    }, 

    render: function() { 
    if (!this.props.loaded) { 
     return this.renderLoadingView(); 
    } else { 
    return (
     <ListView 
      dataSource={this.state.dataSource} 
      renderRow={this.renderRow} 
      style={styles.card} /> 
    ) 
    } 
    }, 
    renderLoadingView: function() { 
    return ( 
     <View style={{alignItems: 'center', alignSelf: 'center', marginTop: 150, justifyContent: 'center'}} > 
     <Text style={{fontSize: 30, fontWeight: '400', color: '#666'}}> Loading ... </Text> 
     </View> 
    ); 
    }, 

    renderRow: function(rowData) { 
    return (
     <CardView 
      name={rowData.name} 
      fullname='xyz' 
      distance='xyz' 
      title={rowData.title} 
      message={rowData.description} 
      score='xyz' 
      stars='xyz' 
      starcolors={colors.General.black} 
      vouched="Example" /> 
    ) 
    } 
}) 

爲什麼它會給我這個?如果我把fetcher放在componentDidMount中,並且如果我把它放在渲染中,它就會觸發無限廣告。

如何更有效地控制此執行/生命週期問題?我也試圖讓它成爲一個說明if (this.props.friendFeed.friend.name !== undefined)的IF聲明,但不管信不信,它只是返回一個紅色屏幕,說this.props.friendFeed.friend.name is undefined。它可能是一個調用Key內的對象的問題嗎?我可以在沒有定義之前調用這樣的東西嗎?

回答

0

我看到兩種可能的解決方案。首先,關於在未定義對象上調用密鑰的最後一個問題。考慮到此對象...

{ 
    foo: { 
    bar: 'text' 
    } 
} 

如果在任何時候fooundefined,你不能檢查是否有子對象鍵也undefined。您需要確定數據加載時可能未定義的最高根對象。

因此,如果fooundefined,則該聲明將失敗:if (foo.bar !== undefined)。但是,這種說法可以:if (foo.hasOwnProperty('bar'))或技術上甚至if (foo !== undefined)

至於你的主要問題,我的猜測是有什麼異步發生在數據解析。這是我如何實現fetch ...

function checkStatus(response) { 
    if (response.status >= 200 && response.status < 300) { 
    return response.text().then((text) => { 
     if (text == "") return "" 
     return JSON.parse(text) 
    }) 
    return response.json() 
    } 
} 

get(id, query) { 
    let url = this.API_URL() + '/' + id + this._generateQuery(query) 
    return fetch(url, { 
    method: 'get', 
    headers: this._headers() 
    }).then(this._checkStatus) 
    .then((data) => { 
     return data 
    }) 

}

通知我怎麼也打入加工身體成文本的承諾側。我會嘗試在你的changeComponent中這樣做,以便它不會調用setState(並隨後將加載設置爲true),直到你確定數據被解析。由於它是內聯的,因此它可能會立即調用setState,然後在完成解析(因爲它僅傳遞變量引用而不是值)時使組件顯示不完整的數據。