Javascript 反应:在设置状态之前触发初始渲染(通过ajax)
我已经设置好主页组件为当前登录的用户呈现UserShow。例如,如果ID为2的用户登录并访问主页,则会显示其UserShow “正常”UserShow正常工作。例如,如果键入/users/18,它将正确渲染。然而,当主页呈现它时,它不工作 我对反应(尤其是它的生命周期方法)是新手,所以我的调试一直是在不同的步骤中抛出警报。我想说,最重要的研究结果是: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的值进行硬编码可以使事情正
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在我的特殊情况下的使用情况?因为它按原样工作。非常感谢!