preivew

我认为: Revert 功能, 是一个 闪卡类 App 的刚需. 而且是必须足够简单明确, 操作应该足够简单便捷的刚需.

原因很简单: 谁都有手滑的时候. 纵然, 基于基于规则, 一个卡片手滑点错 OK 或者 NG, 对最终的记忆效果影响不会太大; 但是心里真的感觉很不舒服. 而且, 严格来说: 立即 Revert 这次操作, 能让闪卡更准确真实的反映用户的记忆状况.

这次的思路, 也很简单. 没有用 Redux 那一套复杂的 Redo/Undo 库. 我知道是可以的. 我记得我以前搞过.

说实话, 需求非常简单. 我也只需要 Undo 用户(其实现在只有我) 的最后一次 NG/OK 操作就行. 甚至都不用持久化, 直接存储到内存里就行. 因为这是一个强即时性的需求. 就像马路上开车, 遇到岔道, 该转向就要立即转向; 错过路口, 再操作方向盘, 可能完全没啥意义了.

我的基础思路:

  • 内存里, 用单独一个变量, 记录最后一次 NG/OK 操作前, 该卡片的几个核心状态:
cardRevertEvent = {
    cardId,
    stage: card.stage,
    reviewToday: card.reviewToday,
    lastStudy: card.lastStudy,
}
  • 然后, 界面上加个 Revert 按钮, 点击就执行 Revert 操作:
<button
    type="button"
    className="inline-flex items-center gap-x-2 rounded-md bg-red-400 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
    onClick={() => {
    if (window.confirm("确定 Revert 最后一次卡片操作吗?")) {
        dispatch(reviewRevertAction())
    }
    }}
>
    Revert卡片操作
</button>
  • Revert 操作本身也非常简单, 就是把最后一次记录的 卡片关键状态, 给还原回去:
reviewRevertAction: {
    reducer(state, action) {
        if (!cardRevertEvent) {
            return
        }

        const info = cardRevertEvent

        const { cardId, stage, reviewToday, lastStudy } = cardRevertEvent
        cardRevertEvent = null

        const card = state.card[cardId]
        card.stage = stage
        card.reviewToday = reviewToday
        card.lastStudy = lastStudy

        localCacheCardState(state)
    }
},

我要写的, 其实就是这些. 但是因为是基于 React + Redux. 可以自动实现UI的动态局部刷新, 所有体验是极好的.

啊! 再次感慨下! docker 下部署的 web 服务, 配合 –mount 本地目录. 这种修改后, 立即生效, 所写即所得的编码体验, 真的是太棒了! 换了其他方式, 我可能还在初始构建代码…