每次 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 的回答中提到的<Link>
组件。
【讨论】:
伟大而直接的答案!我正在将我的旧服务器端应用程序转换为客户端,并想介绍 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。
如果您想从DJSAppContainer
或DJSPage
或PageContainer
两个子视图中的任何一个重定向,您可以通过访问历史属性来实现:
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 的 <Link/>
组件。
似乎历史属性现在已被弃用,并且似乎被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 路由器都会转到服务器的主要内容,如果未能解决你的问题,请参考以下文章
如何通过黄瓜选项通过带有黄瓜功能文件的命令行传递应用程序 URL?