【问题标题】:React-router unintended reload on transitionTo (Chrome)在transitionTo(Chrome)上的React-router意外重新加载
【发布时间】:2015-08-27 13:56:19
【问题描述】:

在基于 React 和 React Router 实现的(单页)应用程序中,我们在使用 router.transitionTo 方法时观察到一种奇怪的模式。

为额外冗长的上下文道歉,但不想错过相关的内容。

假设我们有以下路由器初始化,它是从应用程序的单个“物理”页面调用的:

define([], function () {
    var _Root = React.createClass({
            render : function () {
                return React.createElement(React.addons.CSSTransitionGroup, {/**/},
                React.createElement(Router.RouteHandler, {/**/}));
            }
        });
    var _NotFoundScreen = React.createClass({/**/});
    var _NoDefaultScreen = React.createClass({/**/});
    var routes = (
        React.createElement(Router.Route, {
            handler : _Root,
            path : "/SampleApplication/"
        },
        React.createElement(Router.Route, {
            path : "Transfer",
            handler : Transfer
        }),
        React.createElement(Router.Route, {
            path : "Home",
            handler : Home
        }),
        React.createElement(Router.DefaultRoute, {
            handler : Home || _NoDefaultScreen
        }),
        React.createElement(Router.NotFoundRoute, {
            handler : _NotFoundScreen
        })));
    return {
        init : function () {
            var router = Router.create({
                routes : routes,
                location : Router.HistoryLocation
            });
            router.run(function (rootClass, state) {
                if (state.routes.length === 0) {
                    window.location = state.path;
                }
                React.render(React.createElement(rootClass, state), document.getElementById("reactContainer"));
            });
        }
    }
});

然后我们有一个“转移”页面,其中包含以下内容:

define([], function () {
    var View = (function (_super) {
        /*(...)*/
        function View() {
            /*(...)*/
        }
        View.prototype.render = function () {
            /*(...)*/
            return React.DOM.div(null, React.createElement(Button.Button, {
                    enabled : true,
                    onClick : function () {
                        router.transitionTo("/SampleApplication/Home");
                    },
                    style : "btn",
                    visible : true
                }, "B1"), React.DOM.br(), "form:", React.createElement(Form.Form, {
                    style : "form",
                    visible : true
                }, React.createElement(Button.Button, {
                        enabled : true,
                        onClick : function () {
                            router.transitionTo("/SampleApplication/Home");
                        },
                        style : "btn btn-primary",
                        visible : true
                    }, "B2")));
        };
        return View;
    })(/*(...)*/);
    return View;
});

所以,我们在转账页面上有 2 个按钮 - B1 和 B2。 B2 由“form”元素包裹。当点击时,这两个按钮都能够“导航”到主页。

通过 B1 的导航按预期工作。

B2 的导航揭示了一些特殊的行为。

  • 浏览器网址:host/SampleApplication/Transfer
  • 我们点击B2
  • 我们“导航”到 host/SampleApplication/Home 并在几分之一秒内查看页面内容
  • 几分之一秒后,浏览器 url 更改为 host/SampleApplication/Home?
  • 我们得到一个白屏(好像我们第一次加载/访问应用程序并且它正在初始化)
  • 我们得到渲染页面@host/SampleApplication/Home?

我一直试图找出问题有一段时间了,但似乎没有任何调试产生任何结果。

从 B1 和 B2 导航的执行流程是相同的(直到 React Router 调用 location.push(path))。

此外,这种“仅”发生在 Chrome(桌面和移动)、Opera(移动)和 Android 库存浏览器上,而对于 Firefox(桌面和移动),B1 和 B2 都能够从一个页面导航到另一个页面,而无需任何额外的重新加载或“离开”应用程序的单个物理页面。

我无法找到任何有关类似行为模式的相关信息,这些信息可以解释可能发生的情况。

如果有人能就这里可能发生的事情提供一些见解,将不胜感激。

致以最诚挚的问候,

SYG

【问题讨论】:

  • 您在按钮处理程序中尝试过event.preventDefault() 吗?
  • @Clarkie 为评论喝彩。

标签: javascript google-chrome reactjs single-page-application react-router


【解决方案1】:

好的,问题的根源被确定为按钮元素的默认类型 - 提交(HTML 推荐link)。

由于按钮是在表单元素中呈现的,因此按钮的“onClick”会隐式提交表单,从而导致页面重新加载排队。按钮的“onClick”执行 router.transitionTo,有效地导航到目标页面,然后从表单提交重新加载的“排队”页面立即执行,导致应用程序重新初始化。

通过将按钮元素的类型更改为 button 来“修复”该行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-15
    • 2019-01-18
    • 1970-01-01
    • 2018-01-25
    • 2023-03-03
    • 2021-01-04
    • 2018-01-13
    • 1970-01-01
    相关资源
    最近更新 更多