React:在设置状态之前初始渲染(通过ajax)(React: initial render fires before state is set (via ajax))
我已经进行了设置,因此HomePage组件为当前登录的用户呈现UserShow 。 例如,如果ID为2的用户登录并访问HomePage页面,它将呈现其UserShow 。
“普通” UserShow正常工作。 例如,如果您键入/ users / 18,它将正确呈现。 但是,当HomePage呈现它时,它无法正常工作。
我是React的新手(特别是它的生命周期方法),所以我的调试是在各个步骤中发出警报。 我想说最重要的发现是:
- currentUserID()正在运行并返回正确的ID
- 在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> ) } })
I've set things up so the HomePage component renders UserShow for the current logged in user. For example, if a user with an ID of 2 is logged in and visits the HomePage page, it will render their UserShow.
The "normal" UserShow works correctly. For example if you type in /users/18, it will properly render. However it's not working when HomePage renders it.
I'm new to React (especially its lifecycle methods), so my debugging has been to throw alerts in at various steps. I'd say the most important findings to share are:
- currentUserID( ) is functioning and returns the correct ID
- Hard-coding the value of state.userID within componentDidMount causes things to work correctly
These two points lead me to believe that Render is being called before it can update state.userID with its (correct) return value. Even more specific is that it's rendering before the .success portion of the this.currentUserID() ajax call returns. If this is so, what's the best way to go about not doing an initial render until an ajax call like this completes?
My code is in a state of spaghetti - it's my first time doing front-end routing with JavaScript. I'm also managing sessions via using the user's email as the token in localStorage - I'm new to sessions in JS as well. Please bear with me.
HomePage component:
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 component:
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> ) } })
原文:https://stackoverflow.com/questions/33538352
最满意答案
尝试:
"[Mau_con]![Action Date] Between DateValue([Forms]![frmReportFilter]![txtStartDate]) And DateValue([Forms]![frmReportFilter]![txtEndDate])"
要么:
"([Mau_con]![Action Date] Between DateValue([Forms]![frmReportFilter]![txtStartDate]) And DateValue([Forms]![frmReportFilter]![txtEndDate])) And ([Mau_con]![Advisor Name] = [Forms]![frmReportFilter]![cmbAdvNam])"
Try with:
"[Mau_con]![Action Date] Between DateValue([Forms]![frmReportFilter]![txtStartDate]) And DateValue([Forms]![frmReportFilter]![txtEndDate])"
or:
"([Mau_con]![Action Date] Between DateValue([Forms]![frmReportFilter]![txtStartDate]) And DateValue([Forms]![frmReportFilter]![txtEndDate])) And ([Mau_con]![Advisor Name] = [Forms]![frmReportFilter]![cmbAdvNam])"
相关问答
更多-
电脑二级考试 是考access 还是VPF[2022-06-08]
access -
您需要为日期值格式化格式正确的字符串表达式: Dim dateFrom As Date Dim dateTo As Date dateFrom = DateValue(Forms!formOptions!txtDateFrom.Value) dateTo = DateValue(Forms!formOptions!txtDateTo.Value) strCriteria = "[ActionTime] >= #" & Format(dateFrom, "yyyy\/mm\/dd") & "# And [ ...
-
MS访问限制(MS Access Limit)[2023-05-11]
由于这些行没有任何类型的顺序唯一键号,因此您需要创建一个排名列: 如何在查询中排列记录 您需要确定一次将返回N个行数(N = 10,25,100)。 您需要跟踪用户所处的“页面”以及第一个和最后一个排名的值。 然后,当您为下一页进行调用时,它可能是接下来的N行>或<第一行和最后一行(取决于用户是转到上一页还是下一页)。 我确定有一种方法可以计算最后一页,第一页等。 Since it doesn't appear that you have any type of sequencial unique key ... -
postgres到MS Access(postgres to MS Access)[2022-10-03]
在Windows机器上安装PostgreSQL ODBC驱动程序 。 创建一个指向PostgreSQL数据库的DSN。 启动Access会话并使用DSN导入PostgreSQL表。 过去我已经做了几次,发现它很快捷。 使用ODBC驱动程序进行访问会将PostgreSQL列数据类型转换为与Access兼容的类型。 这种方法应该适用于简单的表格。 但是,如果您的设计使用高级PostgreSQL功能,则这些功能可能无法很好地(或完全)转换为Access。 但是,由于您尚未创建数据库,我鼓励您容忍Access表设计 ... -
查询中的表未链接。 通过拖放链接查询设计器中的相关列,如关系创建 Tables in your query not linked. Link related colums in query designer by drag-and-drop, like relationship creation
-
尝试: "[Mau_con]![Action Date] Between DateValue([Forms]![frmReportFilter]![txtStartDate]) And DateValue([Forms]![frmReportFilter]![txtEndDate])" 要么: "([Mau_con]![Action Date] Between DateValue([Forms]![frmReportFilter]![txtStartDate]) And DateValue([Forms] ...
-
MS Access中的条件字段(Conditional Field in MS Access)[2023-06-12]
在MS Access中,您可以使用内联IIF(条件,true,false) 在你的情况下。 SELECT Laufzettel.ANTRAGSNUMMER, Laufzettel.Versicherungsnummer, IIF(ISNULL(Laufzettel.EPolicierungVSL),1,0) AS dunkel , Laufzettel.AEingangDatenstromZWorkflow , Laufzettel.B ... -
ms access 2010在每年给出条件时没有获取数据(ms access 2010 not getting data when giving the condition year to year)[2022-12-13]
哦伙计。 你意识到这有多糟糕? 遗憾的是,“不知道如何使用数据库”的风格。 是时候阅读有关数据类型的文档了。 好的,我们走了: TaskDate(格式为备忘录) 是的,然而这应该被公开鞭打。 首先,这是一个TEXT字段,第二个是LONG文本,它们的日期永远不会。 两级失败。 如果格式为Memo,则为文本,因此“between”比较文本。 '01 / 01/2012'和'12 / 31 / 2012'` 这是从左到右。 即第一个字母0或1,第二个字母1或2,第4个字母在0和3之间,第5个字母在1和1之间。继续 ... -
你可以接受这个想法并玩它。 将其插入模块 Option Explicit Dim g_ManagerReportFilterEnabled As Boolean Dim g_ManagerReportFilter As String Public Function IsManagerReportFilterEnabled() As Boolean IsManagerReportFilterEnabled = g_ManagerReportFilterEnabled End Function P ...