Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应:在设置状态之前触发初始渲染(通过ajax)_Javascript_Jquery_Ruby On Rails_Ajax_Reactjs - Fatal编程技术网

Javascript 反应:在设置状态之前触发初始渲染(通过ajax)

Javascript 反应:在设置状态之前触发初始渲染(通过ajax),javascript,jquery,ruby-on-rails,ajax,reactjs,Javascript,Jquery,Ruby On Rails,Ajax,Reactjs,我已经设置好主页组件为当前登录的用户呈现UserShow。例如,如果ID为2的用户登录并访问主页,则会显示其UserShow “正常”UserShow正常工作。例如,如果键入/users/18,它将正确渲染。然而,当主页呈现它时,它不工作 我对反应(尤其是它的生命周期方法)是新手,所以我的调试一直是在不同的步骤中抛出警报。我想说,最重要的研究结果是: currentUserID()正在运行并返回正确的ID 在componentDidMount中对state.userID的值进行硬编码可以使事情正

我已经设置好主页组件为当前登录的用户呈现UserShow。例如,如果ID为2的用户登录并访问主页,则会显示其UserShow

“正常”UserShow正常工作。例如,如果键入/users/18,它将正确渲染。然而,当主页呈现它时,它不工作

我对反应(尤其是它的生命周期方法)是新手,所以我的调试一直是在不同的步骤中抛出警报。我想说,最重要的研究结果是:

  • currentUserID()正在运行并返回正确的ID
  • 在componentDidMount中对state.userID的值进行硬编码可以使事情正常工作
  • 这两点让我相信,在Render能够用其(正确的)返回值更新state.userID之前,它已经被调用了。更具体的是,它是在这个.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>
        )
    }
    })
    
    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>
        )
    }
    })
    
    var HomePage=React.createClass({
    getInitialState:函数(){
    返回{
    didFetchData:false,
    userID:null,
    }
    },
    componentWillMount:function(){
    newState=this.currentUserID()
    this.setState({userID:newState})
    //this.setState({userID:2})//对值进行硬编码有效
    },
    currentUserID:函数(){
    if(App.checkLoggedIn()){
    var email=this.currentUserEmail()
    此.fetchUserID(电子邮件)
    }否则{
    警报('没有登录的用户')
    }
    },
    currentUserEmail:function(){
    返回localStorage.getItem('email')
    },
    fetchUserID:function(email){//使用用户的电子邮件查询Rails数据库以返回其ID
    $.ajax({
    键入:“获取”,
    url:“/users/email”,
    数据:{email:email},
    数据类型:“json”,
    成功:功能(数据){
    this.setState({didFetchData:'true',userID:data.user_id})
    }.绑定(此),
    错误:函数(数据){
    警报('错误!无法获取用户id')
    }
    })
    },
    render:function(){
    userID=this.state.userID
    返回(
    )
    }
    })
    
    UserShow组件:

    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>
        )
    }
    })
    
    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>
        )
    }
    })
    
    var UserShow=React.createClass({
    getInitialState:函数(){
    返回{
    didFetchData:false,
    用户名:[],
    userItems:[],
    标题图像:“../users.png”
    }
    },
    componentDidMount:function(){
    this.fetchData()
    },
    fetchData:函数(){
    var params=this.props.params.id
    $.ajax({
    键入:“获取”,
    url:“/users/”+params,
    数据:“数据”,
    数据类型:“json”,
    成功:功能(数据){
    this.setState({didFetchData:'true',用户名:data.user\u name,userItems:data.items,headerImage:data.photo\u url})
    }.绑定(此),
    错误:函数(数据){
    警报('错误!无法将用户加载到用户显示')
    }
    })
    },
    render:function(){
    var userItem=this.state.userItems.map(函数(项){
    返回
    })
    返回(
    {userItem}
    )
    }
    })
    
    您在ComponentMount中所做的初始数据集将无助于设置数据,因为您希望从ajax获取数据。调试用户ID和
    currentUserID函数用于确定您是否从本地存储获取正确的电子邮件以及从服务器获取正确的用户id。其他的就可以了。

    所以在ajax请求返回结果之前,您要做的是避免渲染任何内容

    如果状态是您想要的状态,则可以在render方法中执行检查。如果不是,则返回null、加载程序或其他标记。当componentDidMount随后设置状态时,它将触发重新呈现,因为用户ID随后被设置,它将返回userShow组件

    例如:

    render(){
      if(this.state.userID === null){
         return null; //Or some other replacement component or markup
      }
    
      return (
        <div>
            <UserShow params={{id: userID}} />
        </div>
      );
    
    }
    

    也可以通过在render方法中启动数据获取来避免在此处执行此操作

    fetchUserID()
    fetchData()
    是异步的,但您试图同步使用它们。他们需要在ajax调用完成时通知回调,您的其余代码必须在回调中继续。谢谢@thsorens。将内容从willMount更改为didMount,并在呈现前添加加载检查修复了它。请注意,它希望使用==而不是==。接下来,关于componentWillReceiveProps,请注意ELI5在我的特殊情况下的使用情况?因为它按原样工作。非常感谢!