方法论:为用户操作实施逻辑? (没有客户端和服务器之间的代码重复或不可接受的用户体验)

Methodology: Implementing Logic for User Actions? (Without Code Duplication Between Client and Server or Unacceptable UX)

让我们编一个玩具箱:假设我们有一个应用程序,每个 post 都有一个 "thumb up" 按钮 - 你知道,当点击它时,按钮应该变成蓝色,并且服务器应该存储这个家伙竖起大拇指。

所以我的问题是,实施这个的最佳做法是什么?我有两个天真的解决方案,但我认为它们都有一些缺点。所以我想知道有没有更好的第三种解决方案,或者我的一种是大家做的。


供您参考,这是我的两次尝试:

方法A:点击的时候,触发两个东西。 (1) 直接修改state(比如在Redux中),设置state.thumbup=true,然后React会自动重新渲染UI。同时,(2)向服务器发送一个HTTPpost。当服务器收到它时,它会更新它的数据库(例如 user.setThumbUp(true);repo.save(user);)。

问题是,我必须复制我的逻辑两次,一次在客户端("if click, the state.thumbup becomes 1"),一次在服务器("if client clicks, one location in the database changes to 1").这在我们的例子中很简单,但它违反了 KISS 规则,当动作变得复杂时,很多代码重复...

方法B:点击时,客户端不修改任何本地状态。相反,我们只向服务器发送 HTTP post。然后,服务器接收它,并修改它的数据库。在我们知道服务器已完成其工作后,客户端会触发 HTTP 获取,以获取有关整个页面的最新状态。客户端获取数据后进行渲染,用户看到竖起的大拇指被着色。

当然,这使得重复代码消失了。但是,现在用户将等待很长时间(等待 HTTP 请求)才能看到 UI 已更改。看来这也是很糟糕的...

因此,请问有没有更好的解决办法?还是大家只是单纯的使用第一种方法?非常感谢!

方法A更好。为了解决您的问题:

  1. 逻辑重复:可以这么说,您只需要复制 "write operation"。 reducer 将保存竖起大拇指的状态,而 action creator 将发送 api 请求以在服务器上执行 "thumbs up"。但是按钮的基本接线 -> 竖起大拇指动作保持不变。 React 组件不知道乐观更新,只是渲染它的 props。所以这本身并不是逻辑的重复,你只是添加了更多的逻辑来改进用户体验,这是合法的。

  2. Rollback/error处理:方法A和B可以结合使用。您将发送 api 请求以获得赞许,等待它成功或失败,最后发送一个 GET 请求以获取您试图在服务器上更改的相同资源(因为它是真实的来源)。如果写操作失败,这将回滚乐观更新。或者它在成功时什么都不做,但保证您的商店中有最新的资源。

但是,我猜想 80% 的 React/Redux 应用程序不会进行乐观更新,因为大多数开发人员在快速互联网连接上进行测试,并且根本不知道连接速度慢时糟糕的用户体验。但这是正确的做法。