在我的react-redux-aspnetcore spa上,我启用了服务器端渲染。但是,我使用的是老式的基于cookie的身份验证。所以我没有服务器端访问API的身份验证是必要的。
这是我的动作创建器:
export const actionCreators: AC = {
requestEntries: (weekStartDate: string): ActionCreator => (dispatch, getState) => {
// Only load data if it's something we don't already have (and are not already loading)
if (getState().activeUserEntries.date != weekStartDate && getState().activeUserEntries.isLoading == false) {
console.log('aa');
let fetchTask = fetch(`/api/entries?date=${weekStartDate}`, {
credentials: 'same-origin'
})
.then(response => response.json())
.then((data: EntrySet) => {
dispatch(new ReceiveEntries(weekStartDate, data));
}).catch((a)=>{
dispatch(new InitEntriesState());
});
addTask(fetchTask); // Ensure server-side prerendering waits for this to complete
dispatch(new RequestEntries(weekStartDate));
}
}
};
可以看到fetch
方法有.catch((a)=>{dispatch(new InitEntriesState());});
部分。在服务器端捕获错误,因为身份验证失败,response.json()
抛出异常,因为视图结果不是json字符串。
因此,如果身份验证失败,我调度InitEntriesState()
,这使得我的reducer返回存储部分的初始状态。
最后,我得到了恶毒的警告信息:
Warning: React attempted to reuse markup in a container but the checksum was invalid.
This generally means that you are using server rendering and the markup generated
on the server was not what the client was expecting.
React injected new markup to compensate which works but you have lost many of the
benefits of server rendering. Instead, figure out why the markup being generated
is different on the client or server:
(client) v data-reactid="68">...Loading</div></di
(server) v data-reactid="68"><table class="table
那么我该如何解决这个问题呢?还是我应该改变解决问题的方法?如果有,怎么做?
如果我没听错的话,听起来好像服务器呈现了一个没有经过身份验证的页面,然后当客户端加载时,它呈现了经过身份验证的页面。对吗?你可以通过在浏览器中禁用js来测试这一点,看看服务器自己渲染的内容。
这个神秘的错误消息只是意味着服务器和客户端没有呈现相同的HTML,这意味着服务器端呈现的大部分性能优势都失去了。如果你真的无法让服务器端渲染工作,并且你的大部分应用在服务器端渲染和客户端渲染上看起来完全不同,那么让服务器返回一个加载状态,甚至不尝试渲染react应用程序可能是有意义的。