React的history.push()方法更新了URL但没有在浏览器中导航到该URL

90

我已经阅读了很多有关react-router v4和npm history库的内容,但似乎都没有对我有所帮助。

我的代码在使用history.push()方法更改URL时,到达预期的功能点停止工作。尽管URL正在更改为指定的路由,但按钮推送后并未进行重定向。

我希望在按钮推送时进行简单的重定向,而不需要{forceRefresh:true},这会重新加载整个页面。

import React from 'react';
import createBrowserHistory from 'history/createBrowserHistory';

const history = createBrowserHistory({forceRefresh:true});

export default class Link extends React.Component {
  onLogout() {
    history.push("/signup");
  }
  render() {
      return(
        <div>
          <h1>Your Links</h1>
          <button onClick={this.onLogout.bind(this)}>Log Out</button>
        </div>
      )
  }
}
13个回答

75

你不需要降级到v3,React-Router 4.0.0 完全能够实现OP所要求的功能。

const history = createBrowserHistory();

它是一个自定义的历史记录对象,因此您应该使用<Router>将其与react-router同步,而不是<BrowserRouter>,我假设您正在使用后者。

请尝试使用以下内容:

import React, {Component} from 'react';
import { Router } from 'react-router';
import { Route } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';

const history = createHistory();   

class App extends Component {
   constructor(props){
      super(props);
   }
 
   render(){
       return (
           <Router history={history}>   //pass in your custom history object
                <Route exact path="/" component={Home} />
                <Route path="/other" component={Other} />
           <Router />
       )
   }
}

一旦您通过Router的history属性传入自定义history对象,history.push应该在您的应用程序的任何地方正常工作。(您可能希望将您的history对象放在一个history配置文件中,并将其导入到您想要以编程方式路由的地方)。

更多信息请参见:React Router history object


15
谢谢!这是我看到的唯一一个解释需要在使用history包时使用<Router/>而不是<BrowserRouter/>的答案。 - Chase DeAnda
3
这是我在过去四天搜索中找到的最正确的解决方案。 - Abhinav
2
非常感谢,现在使用<Router>可以正常工作了,但basename在其中停止工作。在<BrowserRouter>中,basename可以工作,但是history无法工作 :-( - Jay
1
非常感谢你。使用BrowserRouter时它无法工作,但是更改为Router并将我的历史记录添加为参数后,它就像魔术般地运行了。 - ncesar
优秀的回答,主要原因是为像我这样的新手编写的。 - Jatin Garg
显示剩余3条评论

46

检查一下是否存在嵌套的BrowserRouter标签。

我在使用react-router v4时遇到了这个问题,但是当我将应用程序改为只在最顶层使用BrowserRouter时,我解决了这个问题,就像下面的示例一样。

ReactDOM.render(
  <BrowserRouter >
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

3
我有同样的问题,但仍然没有解决方案。 - Ruan Duarte
1
感谢您的回答。我在整个应用程序中有几个不同模块中使用了 BrowserRouter。为了使其成功运行,我必须从所有模块中删除 BrowserRouter 标签,并将其保留在应用程序级别上。 - Ritesh Jagga

8

请确保你正在使用

const history = createBrowserHistory({forceRefresh:true});

不是

const history = createBrowserHistory();

我加入了"{forceRefresh:true}"后,成功更新了页面。


10
它重新加载整个页面,我认为这不是预期的行为。 - Traycho Ivanov
1
它也会更新状态。这不是正确的方式。 - Akash Elhance
你真是个救命恩人,正是我所需要的。 - SiggeLund

6

使用react-router-dom中的Router组件,而不是BrowserRouter

// index.js

    import React from "react";
    import ReactDOM from "react-dom";
    import App from "./App";
    import { Router } from "react-router-dom";
    import history from './utils/history'


    ReactDOM.render(
      <Router history={history}>
        <App />
      </Router>,
      document.getElementById("root"));

    serviceWorker.register();


// history.js 

import { createBrowserHistory } from 'history';

export default createBrowserHistory();

在需要导航到其他组件的情况下,导入 history 并使用 push 方法。

import History from '../utils/history'

History.push('/home')


5
渲染这个会在路由改变时刷新。
 `ReactDOM.render(
    <AppContainer>
      <BrowserRouter children={routes} basename={baseUrl} forceRefresh={true}/>
    </AppContainer>,
    document.getElementById("react-app")
  );`

react-router-dom : 4.2.2


2

如果您在渲染时使用了严格模式,请将其删除并重试。

示例:

如果您的渲染方法如下所示:

const root = ReactDOM.createRoot(
  document.getElementById('root')
);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);

将其更改为这样

const root = ReactDOM.createRoot(
  document.getElementById('root')
);

root.render(
  <App />,
);

0
如果您正在使用函数组件,则尝试使用 useHistory 钩子进行推动。
import React from 'react';
import { useHistory } from "react-router-dom";

export default function Link{

  let history = useHistory();

  onLogout() {
    history.push("/signup");
  }

  return(
        <div>
          <h1>Your Links</h1>
          <button onClick={this.onLogout.bind(this)}>Log Out</button>
        </div>
      )
}

0

如果您不想更改路由器或版本,您可以在更新历史记录后强制重新加载页面。

例如:

history.push({
    'pathname': '/signup',
    'key': 'value'
})   
document.location.reload()

0

我有同样的问题。

经过一些搜索,我发现了这个react-router issue

我目前已将 react-router 降级到 v3,并使用 react-router 包中的 browserHistory,它可以正常工作。


是的,我也是这样做的,现在打算继续使用v3。谢谢! - John

0

如果有人使用 react-router-dom v6,

我曾经遇到同样的问题,不得不降级到 v5

然后问题就解决了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接