每次 URL 更改时,带有 browserHistory 的 React 路由器都会转到服务器

Posted

技术标签:

【中文标题】每次 URL 更改时,带有 browserHistory 的 React 路由器都会转到服务器【英文标题】:React router with browserHistory goes to server on every URL change 【发布时间】:2016-06-08 10:52:30 【问题描述】:

我正在做类似的事情:

<Router history=browserHistory>routes</Router>

当我执行上述操作时,只要地址栏中的 URL 更改调用将发送到服务器,但这不是我想要的,我希望第一个页面从服务器加载,但之后只要路由更改组件应仅在客户端加载。我在这里遗漏了什么吗?

在客户端我正在做类似的事情:

ReactDOM.render(
    <Provider store=app.store>
        <Router history=browserHistory>routes</Router>
    </Provider>,
    document.getElementById("app")
);

我的路线看起来像:

const routes = (
    <Route path="/" component=DJSAppContainer>
        <Route path="page" component=DJSPage>
            <Route path="/page/:pageName" component=PageContainer />
        </Route>
    </Route>
);

现在每当我执行location.href = "/page/xyz" 时,它都会转到服务器并加载内容。

【问题讨论】:

每当我遇到这个问题时,这意味着我的客户端 bundle.js 无法创建或无法正常工作。检查未与服务器共享的客户端代码段中是否有任何错误(通常是客户端启动、历史记录、DOM 渲染、存储、中间件等) 您是否在客户端代码中渲染到 dom 中? 是的,我正在客户端代码中渲染到 dom,我已经更新了我的问题。 您是如何导入和创建浏览器历史记录的? 我有这个问题,但只在开发过程中出现在本地——在生产中它消失了。您可以尝试生产构建并查看... 【参考方案1】:

您不应该直接更改location.href。您应该使用以下命令将新的 path 发送到 React:

ReactRouter.browserHistory.push(newPath);

如果你有锚标签,你应该使用@ahutch 的回答中提到的&lt;Link&gt; 组件。

【讨论】:

伟大而直接的答案!我正在将我的旧服务器端应用程序转换为客户端,并想介绍 react-router。您认为更改 location.href 而不是使用 a tags 路由到我的应用程序的旧部分和 react-routers 组件来执行客户端路由是一种可行的方法吗? @RemEmber 我不明白为什么不这样做,但您应该将其作为一个单独的问题提出以获得更详细的答案。【参考方案2】:

我遇到了类似的问题,而 hashHistory 工作没有问题 browserHistory 总是会从服务器加载。我通过记住调用 preventDefault() 来让事情正常进行。这是我的功能:

handleSubmit: function (e) 
    e.preventDefault();
    var username = this.usernameRef.value;
    this.usernameRef.value = '';
    this.context.router.push(`/profile/$username/`);

handleSubmit 在表单上调用 onSubmit。

【讨论】:

【参考方案3】:

React 路由器将当前视图中使用的历史记录作为道具公开。查看他们的文档以了解所有注入的道具here。

如果您想从DJSAppContainerDJSPagePageContainer 两个子视图中的任何一个重定向,您可以通过访问历史属性来实现:

const history = this.props;
history.pushState('/path/to/new/state');

另一方面,如果你做了一些花哨的事情并想从组件外部重定向,试试这个(取自react router docs)

// somewhere like a redux/flux action file:
import  browserHistory  from 'react-router'
browserHistory.push('/some/path')

这两种方法假设您尝试基于一些复杂的逻辑进行重定向,而不是作为点击事件的结果。如果你只想处理点击事件,请尝试使用 react-router 的 &lt;Link/&gt; 组件。

似乎历史属性现在已被弃用,并且似乎被implementation of the link component 中所见的路由器上下文属性所取代。基本上,如果你真的希望你的代码是面向未来的,你应该询问 contextType:

contextTypes: 
     router: object
,

然后从组件的上下文中使用它:

this.context.router.push('/some/path')

【讨论】:

【参考方案4】:

假设您在后端使用节点,请确保根据react-router docs 进行设置。

// send all requests to index.html so browserHistory in React Router works
app.get('*', function (req, res) 
  res.sendFile(path.join(__dirname, 'index.html'))
)

另外,当您在组件之间进行链接并且想要确保使用 react-router 而不是服务器进行路由时,请确保使用Link。希望这能回答你的问题。

【讨论】:

以上是关于每次 URL 更改时,带有 browserHistory 的 React 路由器都会转到服务器的主要内容,如果未能解决你的问题,请参考以下文章

文件目录更改每次重启 Swift iOS

如何通过黄瓜选项通过带有黄瓜功能文件的命令行传递应用程序 URL?

在 url 更改时重新渲染组件

在代码中更改服务参考 URL

每次在 Xcode 4.3 中点击按钮时,如何更改按钮的标题?

如何使用 Selenium 打开带有哈希的 URL?