反应路由器,浏览器后退按钮后如何恢复状态?

nin*_*ino 16 browser router browser-history reactjs

我试图找出当用户使用后退/前进浏览器按钮导航时如何使我的React SPA应用程序保持状态.例如,用户正在填写表格,然后他前后移动并自动恢复表格.

我回顾了很多JavaScript路由器,但似乎没有一个正确解决这个问题......(甚至根本没有).

目前我正在使用React Router 4,这是我采用的模式:

  1. 当以编程方式离开页面时,我首先保存当前页面的状态history.replace(this.state); 然后我移出页面history.push(newLocation)
  2. 当一个页面组件被创建(componentWillMount)我检查this.props.location.state !== undefined,如果是,我恢复它this.setState(this.props.location.state)

我的问题是:上述模式是否正确?建议?有没有更好的和广泛采用的方式?

nin*_*ino 10

过了一会儿,我发现了一个合理的解决方法:

  • 在反应之后,每次this.setState()我保持状态与历史同步使用window.history.replaceState({ key: history.location.key, state: this.state})
  • 当一个"页面"组件被安装或刷新(willMountwillReceiveProps)我检查状态props.params.location.state:如果有一个,我确实恢复它; 如果没有,我会创造一个全新的状态.
  • 当在同一页面上导航时,我不使用路线,我只是使用this.setStatewindow.history.pushState
  • 当在页面外导航时,我只是使用路线并避免在州内传递任何东西

这个解决方案似乎很好用,唯一的小缺点是:

  • state必须是可序列化的
  • this.setState是一个陷阱,因为它是异步的,你不能this.state在它之后使用,除非你做诡计.
  • 在还原或初始化阶段中使用必须由功能来提供初始空的状态,它不能仅仅停留在constructor()Component
  • 在Firefox中,后退按钮随机工作后自动滚动恢复,不知道为什么,但Chrome和Edge都可以.

总的来说,我写了一个PageComponent扩展Component,完成所有初始/恢复工作; 它还会覆盖this.setState使其与历史记录自动同步并避免异步烦恼.