簡體   English   中英

React:在設置狀態之前初始渲染(通過ajax)

[英]React: initial render fires before state is set (via ajax)

我已經進行了設置,因此HomePage組件為當前登錄的用戶呈現UserShow 例如,如果ID為2的用戶登錄並訪問HomePage頁面,它將呈現其UserShow

“普通” UserShow正常工作。 例如,如果您鍵入/ users / 18,它將正確呈現。 但是,當HomePage呈現它時,它無法正常工作。

我是React的新手(特別是它的生命周期方法),所以我的調試是在各個步驟中發出警報。 我要說的最重要的發現是:

  1. currentUserID()正在運行並返回正確的ID
  2. componentDidMount中state.userID的值進行硬編碼會使事情正常工作

這兩點讓我相信Render在被更新state.userID及其(正確的)返回值之前被調用。 更具體的是它在this.currentUserID() ajax調用返回的.success部分之前呈現。 如果是這樣,那么在這樣的ajax調用完成之前,最好的方法是不進行初始渲染?

我的代碼處於意大利面狀態 - 這是我第一次使用JavaScript進行前端路由。 我也通過使用用戶的電子郵件作為localStorage中的令牌管理會話 - 我也是JS中的新會話。 請多多包涵。

主頁組件:

var HomePage = React.createClass({

getInitialState: function(){
    return{
        didFetchData: false,
        userID: null,
    }
},

componentWillMount: function(){
    newState = this.currentUserID()
    this.setState({userID: newState}) 
    // this.setState({userID: 2})   //hard-coding the value works
},

currentUserID: function(){
    if(App.checkLoggedIn()){
        var email = this.currentUserEmail()
        this.fetchUserID(email)
    }else{
        alert('theres not a logged in user')
    }
},

currentUserEmail: function(){
    return localStorage.getItem('email')
},

fetchUserID: function(email){ //queries a Rails DB using the user's email to return their ID
    $.ajax({
        type: "GET",
        url: "/users/email",
        data: {email: email},
        dataType: 'json',
        success: function(data){
            this.setState({didFetchData: 'true', userID: data.user_id})
        }.bind(this),
        error: function(data){
            alert('error! couldnt fetch user id')
        }
    })
},

render: function(){
    userID = this.state.userID
    return(
        <div>
            <UserShow params={{id: userID}} />
        </div>
    )
}
})

UserShow組件:

var UserShow = React.createClass({

getInitialState: function(){
    return{
        didFetchData: false,
        userName: [],
        userItems: [],
        headerImage: "../users.png"
    }
},

componentDidMount: function(){
    this.fetchData()
},

fetchData: function(){  
    var params = this.props.params.id
    $.ajax({
        type: "GET",
        url: "/users/" + params,
        data: "data",
        dataType: 'json',
        success: function(data){
            this.setState({didFetchData: 'true', userName: data.user_name, userItems: data.items, headerImage: data.photo_url})
        }.bind(this),
        error: function(data){
            alert('error! couldnt load user into user show')
        }
    })
},

render: function(){
    var userItem = this.state.userItems.map(function(item){
        return <UserItemCard name={item.name} key={item.id} id={item.id} description={item.description} photo_url={item.photo_url} />
    })
    return(
        <div>
            <Header img_src={this.state.headerImage} />

            <section className="body-wrapper">
                {userItem}              
            </section>
        </div>
    )
}
})

所以你想要做的是避免渲染任何東西,直到你的ajax請求返回你的結果。

如果狀態是您想要的狀態,您可以檢查渲染方法。 如果不是,則返回null,或者加載器或其他標記。 當componentDidMount然后設置狀態時,它將觸發重新渲染,因為然后設置了userID,它將返回userShow組件

例:

render(){
  if(this.state.userID === null){
     return null; //Or some other replacement component or markup
  }

  return (
    <div>
        <UserShow params={{id: userID}} />
    </div>
  );

}

獲取userShow組件中的數據可以這樣完成:

componentWillReceiveProps(nextProps){
    //fetch data her, you'll find your prop params in nextProps.params
}

你也可以通過在render-method中踢數據獲取來避免這樣做。

您的初始數據集在componentWillMount中執行的操作無助於設置數據,因為您想從ajax獲取數據。 調試fetchUserID和currentUserID函數是否從localstorage獲取正確的電子郵件,從服務器獲取用戶ID。 其他人很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM