2017-07-22 73 views
1

大家下午好,呈現一組對象反應

我想顯示的是在初始渲染之前由MongoDB實例提供給我的應用程序的數據。我還沒有成功地做到這一點,無論是出現錯誤還是警告。

這是我正在使用的render方法的一部分。

 <div className="right-column"> 
      <div className="pipeline"> 

       {this.props.tournamentList.map((x,i) => { 
       return <li key={i}>{x.name}</li> 
       })} 

      </div> 

     </div> 

this.props.tournamentList具有物體的像這樣的陣列的值:

tournamentList: 
Array[15] 
0: 
{…} 
1: 
{…} 
2: 
{…} ... 

此列表來通過componentWillMount生命週期方法我的應用程序,因此初始之前呈現。對我來說,我應該可以遍歷數組並製作由我的數據庫提供的動態生成的錦標賽列表。

然而,隨着代碼我提供我得到這樣的警告:

Uncaught (in promise) Error: Objects are not valid as a React child (found: object with keys {prelims, outRounds, notes}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of BuildTournament .

我試過這種方法,創建一個名爲displayTournaments並與類的「管道」,但沒有調用的div內發生,沒有錯誤沒有渲染:

displayTournaments(){ 

     const { tournamentList } = this.props; 

     tournamentList.map((x,i) => { 
        return <li key={i}>{x.name}</li> 
        }) 


    } 

顯然我做錯了什麼,但我不知道是什麼。這是一個實例,我應該使用錯誤消息建議的鍵控片段?比我自己更聰明的人會願意提供一些見解嗎?

乾杯。

+0

在'componentWillMount'生命週期掛鉤執行異步操作並不能保證數據的任何更多的幫助,請在最初的渲染。您需要撥打電話,然後更新您的狀態以觸發重新呈現。你的組件也需要一個無數據渲染狀態。 –

+0

tournamentList的默認道具只是一個空陣列嗎?在你的情況下,在最初的商店。 – Win

回答

2

更新: 對不起,我誤解了你的問題。 Kyle對於加載狀態是正確的。

此外,使用像lodash這樣的庫將允許您以更自然的方式映射對象。本地JavaScript映射方法不能很好地處理對象。

https://www.npmjs.com/package/lodash

你使用它幾乎相同的方式。只是

import _ from lodash 

然後

_.map(objectToMap, (x) => <Component key={x}>{x.thing}</Component>) 
+1

他在對象數組上使用'map'。不需要'lodash'來做到這一點。 –

+1

他不需要使用lodash之類的東西,但它使得陣列中的實際對象更加自然和直觀。你說得對。 – archae0pteryx

+1

更新你的答案,以反映它是可選的,並可能以某種方式使他受益,我將刪除我的投票。 –

1

你將需要有一個加載狀態,如果你在componentWillMountcomponentDidMount生命週期掛鉤讓您的數據。下面的例子將說明這是如何完成的。

class ComponentThatGetsAsyncData extends PureComponent { 
    constructor(props) { 
     super(props); 

     this.state = { 
      tournamentList: [ ] 
     } 
    } 

    componentDidMount() { 
     // use any http library you choose 
     axios.get("/some_url") 
      .then((res) => { 
       // this will trigger a re-render 
       this.setState({ 
        tournamentList: res.data 
       }); 
      }) 
      .catch((err) => { 
       // handle errors 
      }); 
    } 

    render() { 
     const { tournamentList } = this.state; 
     // i'd use something other than index for key 

     // on your initial render your async data will not be available 
     // so you give a loading indicator and when your http call 
     // completes it will update state, triggering a re-render 
     return (
      { 
       tournamentList ? 
        tournamentList.map((x,i) => { 
         return <li key={i}>{x.name}</li> 
        }) : 
        <div className="loading">Loading...</div> 
      } 
     ); 
    } 
} 
+0

我喜歡這個答案,因爲你正在考慮到我的數據的異步加載,我懷疑生命週期鉤子可能與我的功能搞混了。我的印象是「ComponentWillMount」可以避免這種情況,但我認爲不是。如果我使用Redux,這是否重要?如果不是索引的話,你會使用什麼? – m00saca

+1

@ m00saca我親自在'componentDidMount'生命週期鉤子中完成數據加載調用,因爲它確保組件正確安裝。對於密鑰,您可以使用任何獨特的值。使用索引的問題是值始終相同,但項目可能會更改。這將與React的內部協調機制混爲一談。就redux而言,密鑰仍然很重要,而生命週期方法仍將執行相同的功能。 –

+1

@ m00saca儘可能地減少...只要你在http調用的'.then'方法中獲得你的數據,你就會派發一個動作來更新你的商店,然後觸發它如果使用'react-redux'包中的'connect'連接並且您提供了'mapDispatchToProps'函數,那麼在您的組件中重新渲染。你可以在這裏閱讀更多關於這個:https://github.com/reactjs/react-redux/blob/master/docs/api.md –

1

這裏將是一個簡單的解決方案,它將具有加載狀態,錯誤狀態和成功狀態。

首先要注意的是,您將需要使用Object.keys()到您的對象,以映射通過鍵數組,因爲您不能映射普通對象。您還應該注意,地圖將返回每個對象的關鍵字,所以爲了定位關鍵值對,您將需要使用這樣的語法,而不僅僅是執行tournament.name,因爲您要將對象與對象綁定,然後抓取對象價值。

讓我知道,如果你需要這方面的

import React from 'react' 
import Loader from '../Loader' 

const resultList = ({ tournaments, isFetching = true }) => (
<div> 
    { 
     isFetching 
      ? <div> 
        <Loader /><br /> 
        <span>Loading&hellip;</span> 
       </div> 
      : <div> 
        { 
         Object.keys(tournaments).length 
         ? <div> 
           { 
            tournaments.map((key) => (
             <section id={tournaments[key].id} key={key}> 
              <p>{tournaments[key].name}</p> 
             </section> 
            )) 
           } 
          </div> 
         : <div> 
           <p>There are no tournaments....</p> 
          </div> 
        } 
       </div> 
    } 
</div> 
); 

export default resultList 
+0

我會嘗試首先使用你的解決方案,因爲Object.keys很熟悉,但是當我看到你的三元操作的安排和你在那裏的任何'Loader'組件時,我感到困惑。它們是否意味着處理數據的異步加載? – m00saca