Hacker News 中文摘要

RSS订阅

HTMX中的URL驱动状态 -- URL-Driven State in HTMX

文章摘要

文章探讨了在HTMX中使用URL参数作为应用状态的单一来源,以实现可书签、可分享的应用状态管理。通过将过滤、排序、分页和搜索等状态信息嵌入URL,用户可以在不丢失上下文的情况下进行书签、分享或刷新页面。文章还介绍了实现这一模式的三个关键步骤:服务器读取URL参数并渲染视图、表单和HTMX请求保留所有状态、浏览器URL自动更新。这种方法简化了状态管理,无需额外依赖。

文章总结

标题:通过设计实现可书签化:HTMX中的URL驱动状态 | Loren Stewart

主要内容:

在从React转向HTMX时,开发者将复杂的状态管理替换为服务器端的简洁性。然而,仍然需要处理过滤、排序、分页和搜索等功能。那么,这些状态现在应该存放在哪里呢?

答案非常优雅:存放在URL本身。通过将URL参数视为单一的真实来源,开发者可以获得可书签化、可共享的应用程序状态,而无需安装额外的依赖。

模式实践:

例如,URL /?status=active&sortField=price&sortDir=desc&page=2 可以完整地描述当前视图。它不仅仅是一个地址,而是一个完整的状态表示,用户可以将其书签化、分享或刷新而不会丢失上下文。

快速入门:三个关键步骤:

  1. 服务器读取URL参数并渲染相应的视图。
  2. 表单和hx-include在发起HTMX请求时保留所有状态
  3. 浏览器URL通过hx-push-url自动更新

步骤1:服务器读取URL状态:

服务器端点读取查询参数并使用它们来渲染初始视图。例如,通过解析sortFieldsortDirstatuspage等参数,服务器可以应用这些状态来查询数据,并将结果返回给模板进行渲染。

步骤2:表单和隐藏字段保留状态:

在HTML模板中,表单通过隐藏字段保留当前状态,确保在用户进行过滤或排序操作时,所有状态都能被保留并传递给服务器。

步骤3:通过hx-push-url自动同步URL:

使用hx-push-url="true"hx-params="*",HTMX会自动处理URL的更新,将所有表单数据作为查询参数发送到服务器,并更新浏览器URL,同时创建适当的历史记录条目,以便用户可以通过浏览器的后退/前进按钮导航。

生产环境考虑:

  • URL长度限制:浏览器通常支持最多约2000个字符的URL,对于复杂的过滤条件,可以考虑使用缩写参数名称或将部分状态移至服务器端。
  • 参数验证:始终在服务器端验证和清理URL参数,将其视为不可信的用户输入。
  • 测试:由于状态明确地存在于URL和表单值中,这种模式非常易于测试,无需模拟复杂的JavaScript函数。

架构优势:

这种以URL为先的方法带来了多重好处,而无需复杂的客户端状态管理库。每个视图都是可共享的,用户可以将链接发送给同事,对方将看到完全相同的内容。浏览器的后退按钮可以按预期工作,返回之前的过滤状态。SEO也得到了内置支持,因为搜索引擎可以爬取每个状态组合。调试体验透明,因为当前状态始终显示在地址栏中。

通过将URL作为状态存储,开发者不仅是在利用Web平台,而且是在与其协同工作。这种模式从简单的排序扩展到复杂的多过滤界面,同时保持了HTMX最初的简洁性。

结论:

下次当开发者考虑使用状态管理库时,不妨思考一下,是否URL已经足够。在许多情况下,URL不仅足够,而且更为优越。

评论总结

评论主要围绕URL作为状态管理的核心展开,观点多样且具有争议性。以下是总结:

支持URL作为状态管理的观点: 1. URL作为状态管理的优势:多位评论者认为将状态存储在URL中是一种经典且有效的模式,尤其适用于书签和分享功能。例如,PaulHoule提到这是1990年代Web应用的经典模式,而heimdall强调理解URL的工作原理对支持深度链接非常重要。 - "This is a classic pattern of web applications from the 1990s." (PaulHoule) - "Learning why URLs work the way they work is still extremely useful." (heimdall)

  1. URL的灵活性和扩展性:o11c指出可以通过location.hash存储更长的状态,而Twey建议使用唯一ID来确保URL的可书签性。
    • "Note that you can store longer state in the fragment (location.hash)." (o11c)
    • "To get truly bookmarkable list URLs, the best approach is ‘page starting from item X’." (Twey)

反对或质疑URL作为单一状态源的观点: 1. 状态管理的复杂性:btown认为URL不能作为单一的状态源,因为UI的状态分为“进行中”、“已提交”和“已加载”三种,不同应用场景需要不同的处理方式。 - "Hard disagree that there can be a single source of truth." (btown) - "One size does not fit all." (btown)

  1. 框架和工具的不足:DimmieMan批评现有框架对URL参数处理的支持不足,认为开发者花费大量时间处理异步请求,而框架却缺乏对URL参数的友好支持。
    • "Huge amount of dev time spent being able to execute asynchronous functions to the backend seamlessly." (DimmieMan)
    • "Even tools like sveltekit have next to zero support." (DimmieMan)

其他相关观点: 1. 工具和库的推荐:cadamsdotcom建议将URL状态管理封装为React钩子,而cloudking推荐使用Alpine.js作为轻量级的React替代方案。 - "Does something like this exist?" (cadamsdotcom) - "Alpine.js is pretty powerful and capable for building reactive SPAs." (cloudking)

  1. 历史与创新:TimTheTinker回顾了早期使用jQuery和ExtJS时通过location.hash管理状态的经验,而rorylaitila提出了在HTMX中使用“sync-params”来同步页面链接状态的用例。
    • "Just read from location.hash during page load and write to it when the form state changes." (TimTheTinker)
    • "In my progressive enhancement library I call this ‘sync-params’." (rorylaitila)

总结:URL作为状态管理的核心有其优势,尤其在书签和分享功能上表现突出,但也存在复杂性和框架支持不足的问题。开发者应根据具体需求选择合适的工具和策略。