在页面刷新时反应路由和持久性
React routing and persistence on page refresh
我将 React 与 react-router 和 Reflux 一起用作我的数据存储,但我不确定如何最好地处理持久性以允许页面刷新。
我的组件通过 Reflux.connect 连接到商店,但由于商店从后端获取数据,因此当组件首次初始化和呈现时它尚不可用。
当用户从一开始就进入我的应用程序时,所有这些数据都会按顺序加载并在需要时可用,但如果在进一步的路径下触发页面刷新,React 会尝试呈现依赖的组件关于尚不存在的数据。
我通过在 LocalStorage 中不断保存数据副本并从 Reflux 存储 getInitialState() 提供该数据来解决这个问题,以便所有组件在呈现之前获取数据。
我想知道这样做是否正确。当由于某种原因本地存储数据被清除或损坏时,界面变为空白,因为组件无法访问正确的数据。子结构和属性不存在并触发 javascript 错误。这似乎是一个混乱且不可靠的解决方案。
我很想知道用什么模式来解决这个问题。
------编辑-----
回复WiredPrairie评论:
1) 为什么要用 getInitialState 中的数据初始化组件?
当我的组件使用 Reflux.connect 时,它们在第一次呈现时还没有处于其状态的数据,因为商店仍需要获取其数据。我的视图目前不能很好地处理未定义的数据。通过在 getInitialState() 中从 Reflux 存储返回本地存储的缓存,所有连接的组件将在第一次渲染调用之前获取该数据。
2) 是什么导致页面刷新,为什么不能像第一次一样加载数据?
这主要是我在进行编辑时必须围绕 livereload 刷新页面的解决方法(稍后会考虑使用 react-hotloader,但还不是一个选项),但用户也可以在某个地方点击刷新在我的嵌套视图中,这会产生相同的效果。当他们手动刷新时,他们并没有在开始时进入应用程序。
3) 当组件连接到商店的更改事件时,为什么它们不更新?
他们会更新,但就像我说的,他们现在不处理空数据,在第一次渲染时他们会错过它,等待商店取东西。我可以让我的所有视图都能优雅地处理空数据,但这会增加很多样板代码。
从目前的回复来看,我感觉我对 localStorage 所做的是常见的做法。在 localStorage 或 sessionStorage 或类似的东西中本地缓存内容,并在刷新后立即提供该数据。
我应该通过在 localStorage 无法正常工作的奇怪情况下优雅地处理空数据来使我的观点更加稳健。
我一直在 sessionStorage 的 emitChange() 触发时缓存每个 Store,如果存在缓存数据则从 sessionStorage 初始化存储,否则为空值。如果视图可以处理空值,这似乎可行,无论如何这可能是个好主意(听起来这是您的主要问题)。
我建议让您的视图优雅地处理没有数据的情况,如果缓存不可用则使用空值初始化所有内容,然后调用后端以在数据 returns。
我还没有尝试过 Reflux,但在常规的 Flux 中它看起来像这样(也许你可以应用相同的原理):
var _data;
if (sessionStorage.PostStore)
_data = JSON.parse(sessionStorage.PostStore);
else {
_data = {
posts: null
};
BackendAPI.getPosts(function(err, posts) {
if (posts) {
PostActions.setPosts(posts);
}
});
}
...
AppDispatcher.register(function(payload) {
var action = payload.action;
switch (action.actionType) {
...
case Constants.SET_POSTS:
_data.posts= action.data.posts;
break;
default:
return true
}
// Update cache because state changed
sessionStorage.PostStore = JSON.stringify(_data);
PostStore.emitChange();
return true;
});
我将 React 与 react-router 和 Reflux 一起用作我的数据存储,但我不确定如何最好地处理持久性以允许页面刷新。
我的组件通过 Reflux.connect 连接到商店,但由于商店从后端获取数据,因此当组件首次初始化和呈现时它尚不可用。
当用户从一开始就进入我的应用程序时,所有这些数据都会按顺序加载并在需要时可用,但如果在进一步的路径下触发页面刷新,React 会尝试呈现依赖的组件关于尚不存在的数据。
我通过在 LocalStorage 中不断保存数据副本并从 Reflux 存储 getInitialState() 提供该数据来解决这个问题,以便所有组件在呈现之前获取数据。
我想知道这样做是否正确。当由于某种原因本地存储数据被清除或损坏时,界面变为空白,因为组件无法访问正确的数据。子结构和属性不存在并触发 javascript 错误。这似乎是一个混乱且不可靠的解决方案。
我很想知道用什么模式来解决这个问题。
------编辑----- 回复WiredPrairie评论:
1) 为什么要用 getInitialState 中的数据初始化组件?
当我的组件使用 Reflux.connect 时,它们在第一次呈现时还没有处于其状态的数据,因为商店仍需要获取其数据。我的视图目前不能很好地处理未定义的数据。通过在 getInitialState() 中从 Reflux 存储返回本地存储的缓存,所有连接的组件将在第一次渲染调用之前获取该数据。
2) 是什么导致页面刷新,为什么不能像第一次一样加载数据?
这主要是我在进行编辑时必须围绕 livereload 刷新页面的解决方法(稍后会考虑使用 react-hotloader,但还不是一个选项),但用户也可以在某个地方点击刷新在我的嵌套视图中,这会产生相同的效果。当他们手动刷新时,他们并没有在开始时进入应用程序。
3) 当组件连接到商店的更改事件时,为什么它们不更新?
他们会更新,但就像我说的,他们现在不处理空数据,在第一次渲染时他们会错过它,等待商店取东西。我可以让我的所有视图都能优雅地处理空数据,但这会增加很多样板代码。
从目前的回复来看,我感觉我对 localStorage 所做的是常见的做法。在 localStorage 或 sessionStorage 或类似的东西中本地缓存内容,并在刷新后立即提供该数据。
我应该通过在 localStorage 无法正常工作的奇怪情况下优雅地处理空数据来使我的观点更加稳健。
我一直在 sessionStorage 的 emitChange() 触发时缓存每个 Store,如果存在缓存数据则从 sessionStorage 初始化存储,否则为空值。如果视图可以处理空值,这似乎可行,无论如何这可能是个好主意(听起来这是您的主要问题)。
我建议让您的视图优雅地处理没有数据的情况,如果缓存不可用则使用空值初始化所有内容,然后调用后端以在数据 returns。
我还没有尝试过 Reflux,但在常规的 Flux 中它看起来像这样(也许你可以应用相同的原理):
var _data;
if (sessionStorage.PostStore)
_data = JSON.parse(sessionStorage.PostStore);
else {
_data = {
posts: null
};
BackendAPI.getPosts(function(err, posts) {
if (posts) {
PostActions.setPosts(posts);
}
});
}
...
AppDispatcher.register(function(payload) {
var action = payload.action;
switch (action.actionType) {
...
case Constants.SET_POSTS:
_data.posts= action.data.posts;
break;
default:
return true
}
// Update cache because state changed
sessionStorage.PostStore = JSON.stringify(_data);
PostStore.emitChange();
return true;
});