React:在设置状态之前初始渲染(通过ajax)

时间:2015-11-05 06:55:59

标签: javascript jquery ruby-on-rails ajax reactjs

我进行了设置,以便 HomePage 组件为当前登录的用户呈现 UserShow 。例如,如果ID为2的用户登录并访问 HomePage 页面,则会呈现其 UserShow

“正常” UserShow 正常运行。例如,如果您键入/ users / 18,它将正确呈现。但是当 HomePage 呈现它时,它无法正常工作。

我是React的新手(特别是它的生命周期方法),所以我的调试是在各个步骤中发出警报。我要说的最重要的发现是:

  1. currentUserID()正在运行并返回正确的ID
  2. componentDidMount 中对 state.userID 的值进行硬编码会导致内容正常工作
  3. 这两点让我相信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>
        )
    }
    })
    

2 个答案:

答案 0 :(得分:3)

所以你要做的就是避免渲染任何东西,直到你的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中踢数据获取来避免这样做。

答案 1 :(得分:0)

您的初始数据集在componentWillMount中执行的操作无助于设置数据,因为您想从ajax获取数据。调试fetchUserID和 currentUserID函数是否从localstorage获取正确的电子邮件,从服务器获取用户ID。其他人很好。