所以我对此进行了很长时间的研究,并且对网上找到的任何黑客解决方案都不满意,我自己也没有找到解决方案。
背景: React 18 为其组件添加了挂载 -> 卸载 -> 重新挂载行为,以帮助检测组件代码中的杂质。这在开发人员中引发了很多困惑,我想深入了解某个谈论太少的用例。
问题 在大多数情况下,事物可以是纯粹的,因此行为选择没有问题。然而,有些任务本质上是不纯粹的,而且业界似乎已经解决了一些棘手的问题,需要增加更多的复杂性和更多的 npm 库使用来解决这个问题。
示例 对于我的用例,我尝试处理一个非常常见的身份验证流程,并将授权代码发送到我的私有 API 以检索令牌。现在,此授权代码仅供使用一次,服务器将正确拒绝任何进一步从中获取访问令牌的尝试。
这意味着这项任务本质上是不纯粹的,对此无能为力。
实际逻辑如下:
code
查询参数。如果存在,它将发出发布请求以将其交换为访问令牌和新的刷新令牌。如果不存在,它将把用户重定向到身份验证提供商托管的登录 UI,以便用户输入其凭据。然后,该托管登录 UI 将使用 code
查询参数将用户重定向到我的登录页面。网上找到的解决方案 我在尝试解决此问题时遇到了多种解决方案,但对其中任何一个都不满意。我将很快解释,如果可能的话,我希望找到一个实际的解决方案来解决这个问题,而不是以下创可贴解决方案。
解决方案1:第三方库 使用这些获取库之一(React Query、useSWR)来管理缓存和请求重复数据删除。
这是“推荐”的解决方案,但我感觉完全不合适,因为您基本上只是修补问题并将 MB 添加到您的捆绑包中。归根结底,您并没有使该功能变得纯粹,因此这实际上违背了 React 开发人员的建议,即不尝试阻止多次调用,而是尝试使其变得无关紧要。问题是在这种情况下你不能让它变得无关紧要,因为如果多次使用,该验证码将被拒绝。
解决方案2:useRef 您可以使用 ref 来处理本地状态并检查其值来处理是否进行令牌交换调用。
这只是一个 hack,尽管对我来说这是迄今为止最干净的解决方案。复杂性保持较低,并且捆绑包大小不会增加。唯一的缺点是它看起来不直观且令人困惑,这需要开发人员更深入的反应知识,因此是一个可维护性问题。
解决方案 3:缓存响应 这似乎是一个安全问题,因为您现在可以通过复制请求来获取/窃取访问令牌。
解决方案 4:删除严格模式 看起来非常错误,但实际上,在我看来,如果保持一定的开发人员质量,这可能是最好的解决方案。归根结底,严格模式双重渲染是 React 开发人员做出的范例选择,这并非没有问题。最重要的是,您现在拥有一个与生产环境工作方式不同的开发环境。
但这也意味着移除一个相当方便的安全网。
结论 尽管我可以想到可以开发的解决方案,但我还没有找到令人满意的解决方案。也许它已经存在,而我却没有意识到。基本上需要有一个标准,例如钩子,来运行本质上不纯净的代码。为此,我可以轻松地从解决方案 2 中找到一个钩子,但也许有些东西是我没有想到的。也许我可以在某个地方放置令牌交换逻辑,使其不会触发两次。
非常欢迎您的意见。现在我会选择解决方案2,因为这是最不永久的解决方案。