2017-05-22 83 views
3

很抱歉,如果這是在文檔中的某個地方很明顯,但我想等到我的狀態正在渲染的子組件之前父組件設置:React Native:創建API請求,設置狀態,然後渲染?

轉述:

class Parent extends Component { 

    componentWillMount() { 
    firestack.database.ref() 
     .then((snapshot) => { 
     this.setState({myVal: snapshot.val}) 
     }) 
    } 

    render() { 
    // Renders before request finishes setting state, 
    // Child component receives an undefined val 
    return (
     <ChildComponent 
     myVal={this.state.myVal} 
     /> 
    ) 
    } 
} 

之前我渲染命中請求結束,所以我無法將新狀態傳遞給子組件的構造函數。我該如何正確地做到這一點? 希望這是對某人低掛果。

回答

4

首先,我建議將您的異步請求移動到componentDidMount。不是強制性的,但它是生命週期中更好的一點。無論如何,你的組件需要能夠處理myVal == undefined

然後,不會使子組件,直到myVal可用:

render() { 
    return (
    <div> 
     { this.state.myVal && <ChildComponent myVal={this.state.myVal} /> } 
    </div> 
) 
} 

或許,呈現一個微調,而不是:

render() { 
    return (
    <div> 
     { this.state.myVal 
     ? <ChildComponent myVal={this.state.myVal} /> 
     : <Spinner /> 
     } 
    </div> 
) 
} 

注:

  • 你JSX內部不能使用if,所以這個不太猶太人使用的需要才能保持語法緊湊。一種常見的模式。

  • 您可以有一個this.state.isReady布爾值,而不是詢問是否存在特定值。另一種常見模式。

  • 如果ChildComponent是您要渲染的唯一元素,則您可能不需要包裝,但通常是因爲某種原因或其他因素。

+0

偉大的提示在這裏,謝謝! – AlxVallejo

+0

'this.state.myVal &&'結構有兩個小問題。起初,它忽略了'0'或其他非定義的非未定義值。另外它輸出'0'爲'0'值 – lunochkin

+0

更好的是,你們都應該得分 – AlxVallejo

0

建議您在componentDidMount之內完成您的API調用,而不是componentWillMounthttps://facebook.github.io/react/docs/react-component.html#componentdidmount

在此方法中設置狀態將觸發重新呈現。

+0

是的,除此之外,這並沒有在我的子組件中設置狀態,因爲子組件的構造函數最初只被命中一次。 – AlxVallejo

+0

您可以在'constructor'中設置一個默認狀態,檢查Parent的render方法中的值的初始化(像@ lunochkin的建議),或者檢查Child的render方法中的值的初始化。 – user2340824

2

如果是需要ChildComponentmyVal參數,你只需要做到這一點父:

return (
    {this.state.myVal !== undefined && 
    <ChildComponent 
     myVal={this.state.myVal} 
    /> 
    } 
) 

然後反應將呈現,第一時間空字符串和不斷變化的狀態後,將與再次渲染填充myVal值。

另外,正如在另一個答案中提到的那樣,使用componentDidMount要好得多。