React-Router 组件在转换时卸载

React-Router component unmounting on transition

我正在使用 React-Router 来浏览我的移动应用程序。出于某种原因,我的组件在每次转换时都会卸载,然后在 "back" 上重新安装。这会导致状态丢失和滚动位置丢失。我没有在任何地方做 "ignoreScrollPosition",所以我很困惑可能是什么原因造成的。

我正在使用 Reflux 来管理我的状态,并使用 Cordova/Phonegap 为手机编写应用程序。有没有人 运行 之前使用 Cordova/Phonegap 遇到过这个问题?

这是我用于路由器的代码:

var React = require('react');
var Reflux = require('reflux');
var Router = require('react-router');
var Route = Router.Route;
var DefaultRoute = Router.DefaultRoute;
var RouteHandler = Router.RouteHandler;

var App = React.createClass({
    render: function () {
        return (
            <RouteHandler/>
        );
    }
});

...

var routes = (
    <Route handler={App} path="/">
        <DefaultRoute handler={LaunchScreen} />
        <Route name="sample" path="/sample" handler={SampleScreen} />
        ...
    </Route>
);

Router.run(routes, function (Root) {
    React.render(<Root/>, document.body);
});

我相信为了完成您想要的,您需要使用 Router.HistoryLocation 而不是默认值 (HashLocation)。这是因为 HistoryLocation 使用 HTML5 历史记录 API (即 pushState() )来处理 URL 导航,因此您可以点击浏览器 'back'功能而无需重新安装您的组件。

但是,您必须修改您的服务器以在发出初始页面加载请求时加载正确的页面。我不确定 Android 你会怎么做,但这应该可以解决你的问题。


路由器示例:

Router.run(routes, Router.HistoryLocation, function (Root) {
    React.render(<Root/>, document.body);
});

服务器示例(带 Express 的节点)

app.get('*', function (req, res) {
  res.render('index');
});

React Router - History Location

原来这个问题和我使用Flexbox有关。我的 body 没有滚动,而是其中的一个元素。

我的 flexbox UI 看起来像这样:

+----------------+
|    .header     |
+----------------+
|                |
|    .content    |
|                |
+----------------+
|    .footer     |
+----------------+

body {
     display: flex;
     flex-direction: column;
     ...
}
.content {
     flex: 1;
     overflow-y: auto;
     ...
}

这意味着 .content 元素而不是文档 body 正在滚动。似乎 React-Router 跟踪文档 body.

的滚动位置

因此,为了解决这个问题,我对 .header.footer 使用了 position: fixed,并放弃了使用 flexbox 以这种方式呈现核心 UI。结果,文档 body 现在滚动并且 React-Router 跟踪它。

作为一个额外的好处,浏览器在绘制期间似乎性能更高。