我有两页几乎相同的页面,但一个有一些额外的元素要显示,另一个没有。没有什么比一些私人用户数据或身份验证更有趣了:页面是纯静态的。
所以我想要的是在同一个 url 下显示这两个页面之一,这取决于存储在用户设备上的参数(很可能是 cookie)。
我只看到三个解决方案,每个都有自己的问题:
坚持使用静态方法,只需将其设为两个不同的页面,具有两个不同的 urls。我不喜欢这种方法,因为这些页面具有相同的目的,并且我不希望用户共享同一页面的两个不同链接。
停止将其视为静态,并
getServerSideProps
根据 cookie 使用和渲染不同的组件。当然我也不喜欢这种方法:页面不再是静态的,即它失去了它的简单性,getServerSideProps 禁用了静态优化,因此请求处理得更慢。坚持静态方法,并在客户端处理逻辑:根据 cookie 或 localStorage 呈现不同的组件。虽然它没有前两种方法的缺点,但我也不喜欢这种方法,因为由于客户端和服务器的初始渲染不同,所以当 DOM 被替换时,你会遇到“内容跳跃”(类似于这个一个,但我的情况具有更复杂的性质)。除了内容跳转之外,您在开发模式下会在控制台中收到警告:
Warning: Did not expect server HTML to contain a ...
, - 感谢react-dom
(否则将更难跟踪此类问题)。
第三种选择似乎是最好的,但并不理想。我会暂时将这种方法用于我的事情,但我想至少打开对话来解决这个问题,并最终找到解决方案。
UPD。
看来你们甚至无法想象这是可能的。首先,让我解释一些幼稚的“立即”方法的问题(“立即”是因为它是出现在脑海中的第一个解决方案,而不是因为它“快速”):
更复杂的样式避免内容跳跃。虽然可以设置恒定高度(而不是默认高度
height: auto
),所以整体页面高度不会改变,但这不仅是一个过于严格的约束,从设计角度来看很难处理(有时你只是不能给元素一个恒定的高度),但它也没有解决另一个问题:闪烁。处理路由逻辑的自定义服务器,仅此而已。它甚至比选项 #2(使用 getServerSideProps)更糟糕——它全局禁用静态优化,不仅针对某个页面,而且针对整个应用程序。更不用说它不能部署到 Vercel。这是反 NextJSy。太糟糕了。
我花了一整天的时间来处理这个问题,现在让我描述一个可能解决问题的潜在方向:PWA 缓存。很快:它应该类似于选项#1(具有两个不同的静态页面),但是通过管理 PWA 缓存解决了不同 url 的问题。
所以默认情况下我们显示一个页面,在某些用户交互之后,我们运行cache.put(request, response)
, - 其中响应是第二个页面,所以我有点交换一个页面与另一个页面,然后,在访问这个 url 时,它最初显示有适当的元素,虽然 url 没有改变(引擎盖下的缓存正在使用另一个 url,但在浏览器中它是相同的 url)。在 MDN 上,有一个示例说明当您尝试恢复失败的请求时如何做到这一点,但也可以在任何事件上执行此操作:用户交互也是如此。
有用的网址
恢复失败的请求文章
CacheFirst
策略文档(这里似乎是最合适的)
TL;博士
虽然我看到了使用 PWA 的潜在解决方案,但我不会急于庆祝这一发现, - 我还没有工作示例。我不确定我什么时候会有那个, - 很多事情要做,等等。但希望我有更多的时间,我会弄清楚这一点,并认为这个问题已经解决。可能不会很快。欢迎使用代码示例/要点/存储库。