我有一个特定的商店 - 让我们称之为AuthStore
- 它包含一个认证脚本并保留令牌,这是所有API请求的重要参数。所以我需要的是在任何其他商店请求令牌之前触发auth脚本并存储令牌。
如果在webapp
加载时检索到令牌,则我的代码有效。但是,如果用户看到的第一个页面是需要由另一个商店加载的动态数据的页面,那么在AuthStore
实际拥有它之前,其他商店有时会从AuthStore
请求该令牌。
如何避免这种情况并确保在其他商店请求之前存在令牌?
答案 0 :(得分:2)
我认为你不应该执行同步AJAX调用。
我不详细了解您的实施情况,但让我们假设我们正在点击page/with/dynamic/data
必须进行身份验证:
var getStateFromStores = function() {
return {
authToken: AuthStore.getToken(),
dynamicData: FooStore.getAll()
}
}
var PageWithDynamicData = React.createClass({
getInitialState: function() {
return getStateFromStores();
},
componentDidMount: function() {
AuthStore.addChangeEventListener(this._onChange);
FooStore.addChangeEventListener(this._onChange);
},
componentWillUnmount: function() {
AuthStore.removeChangeEventListener(this._onChange);
FooStore.removeChangeEventListener(this._onChange);
},
render: function() {
if (!authToken || dynamicData.length == 0) {
return (
<p>Loading</p>
)
}
if (dynamicData.length == 0) { //we could be authenticated but dynamic datas are not retrievied yet
return (
<p>Loading</p>
)
}
return dynamicData.map(function (data) {
return <Foo data={data}/>
});
}
_onChange: function() {
this.setState(getStateFromStores());
}
});
AuthStore
应该将token
存储在其缓存中,并在第一次调用AuthStore.getToken()
时通过ajax调用检索它。当此ajax调用解析时,它将触发TOKEN_RECEIVED
之类的操作。 AuthStore
将通过更新其内部token
状态来响应此操作,以存储收到的token
,以便下次我们需要时,我们不需要再进行另一次ajax调用。然后,AuthStore
发出更改。
全部放在一起:
page/with/dynamic/data
PageWithDynamicData
通过getStateFromStores
AuthStore.getToken()
被调用,此时它没有任何令牌,因此他触发ajax调用(可能通过某个WebAPIUtils
模块)来检索它(异步)。FooStore.getAll()
被调用。同样在这里,缓存中没有数据,因此调用API来检索数据(异步)。this.state.authToken
和this.state.dynamicData
,PageWithDynamicData
呈现加载状态示例:的
++++++++++++++++++++++
+ +
+ "loading" +
+ +
++++++++++++++++++++++
因为我们运行异步请求所以完全合理。让我们看看会发生什么:
FOO_DATA_RECEIVED
操作。FooStore
通过更新其内部状态以包含接收的数据来响应此操作。FooStore
发出更改AuthStore.getToken()
已经处于待处理状态,因此我们什么都不做(这可以通过Promise
完成,但不在此问题的范围内)FooStore.getAll()
现在返回提取的数据PageWithDynamicData
呈现与之前完全相同。发生相同的渲染:
++++++++++++++++++++++
+ +
+ "loading" +
+ +
++++++++++++++++++++++
TOKEN_RECEIVED
AuthStore
通过使用收到的令牌更新其内部状态并发出更改来响应此操作PageWithDynamicData
收到更改,对AuthStore.getToken()
和FooStore.getAll()
的调用现在返回正确的数据PageWithDynamicData
现在呈现数据:该页面现在将数据呈现给经过身份验证的用户:
++++++++++++++++++++++
+ +
+ - "some data" +
+ - "another one" +
+ - "..." +
+ +
++++++++++++++++++++++
重要提示:这不是“如何在我的React应用程序中处理身份验证”的答案,因为在这种情况下我们应该使用一些会话存储或其他什么。但这里的重点是展示我们如何在做其他任何保持单向数据流的事情之前“等待”发生一些事情,这要归功于Flux。
答案 1 :(得分:0)
您需要确保令牌的请求是&#34;同步&#34;与默认&#34;异步&#34;。在测试时,我使用jQuery进行XHR调用,并遇到了类似的情况。 jQuery有一个属性,你可以设置同步调用,它会在进一步执行代码之前等待结果。
<强>更新强>
function xhr() {
return $.ajax({
type: "GET",
url: "/url/to/data/here",
async: false
}).responseText;
}
这可能需要一些修改,这是我的头脑。如果您打算使用jQquery,请参阅以下文档:jQuery Ajax