11

根據瀏覽歷史記錄,我必須實現一些業務邏輯。用react-router檢測路由更改

我想要做的是這樣的:

reactRouter.onUrlChange(url => { 
    this.history.push(url); 
}); 

有沒有辦法接收來自反應路由器當URL被更新的回調?

+0

什麼版本的react-router是你使用的嗎?這將決定最好的方法。一旦你更新了,我會提供一個答案。也就是說,[withRouter](https://reacttraining.com/react-router/web/api/withRouter) HoC可能是您製作組件位置的最佳選擇,它可以隨時更新您的組件({match,history和location}),這樣您就不需要手動訂閱和取消訂閱事件。這意味着很容易與功能無狀態組件以及類組件一起使用。 –

回答

12

嘗試檢測路由更改時,可以使用history.listen()函數。考慮到您使用的是react-router v4,請使用withRouter HOC包裝您的組件,以獲得history支持。

history.listen()返回unlisten函數。你會用這個來傾聽unregister

您可以配置像

index.js

ReactDOM.render(
     <BrowserRouter> 
      <AppContainer> 
        <Route exact path="/" Component={...} /> 
        <Route exact path="/Home" Component={...} /> 
      </AppContainer> 
     </BrowserRouter>, 
    document.getElementById('root') 
); 

,然後在AppContainer.js

class App extends Component { 

    componentWillMount() { 
    this.unlisten = this.props.history.listen((location, action) => { 
     console.log("on route change"); 
    }); 
    } 
    componentWillUnmount() { 
     this.unlisten(); 
    } 
    render() { 
    return (
     <div>{this.props.children}</div> 
    ); 
    } 
} 
export default withRouter(App); 

從歷史docs您的路線:

你可以聽使用改變當前位置 history.listen

history.listen((location, action) => { 
     console.log(`The current URL is ${location.pathname}${location.search}${location.hash}`) 
    console.log(`The last navigation action was ${action}`) 
}) 

位置對象實現了window.location 接口的一個子集,包括:

**location.pathname** - The path of the URL 
**location.search** - The URL query string 
**location.hash** - The URL hash fragment 

位置還具有以下屬性:

location.state - 這個位置不存在於URL一些額外的狀態

location.key(在createBrowserHistorycreateMemoryHistory支持) - 表示該位置(支持 在createBrowserHistorycreateMemoryHistory)的唯一字符串

作用是取決於用戶 到達當前URL的方式,其中一個爲PUSH, REPLACE, or POP

當您使用反應路由器V3可以從history包使用history.listen()如上所述,或者您也可以使用browserHistory.listen()

您可以配置和使用您的路線一樣

import {browserHistory} from 'react-router'; 

class App extends React.Component { 

    componentDidMount() { 
      this.unlisten = browserHistory.listen(location => { 
       console.log('route changes'); 

      }); 

    } 
    componentWillUnmount() { 
     this.unlisten(); 

    } 
    render() { 
     return (
       <Route path="/" onChange={yourHandler} component={AppContainer}> 
        <IndexRoute component={StaticContainer} /> 
        <Route path="/a" component={ContainerA} /> 
        <Route path="/b" component={ContainerB} /> 
      </Route> 
     ) 
    } 
} 
+0

我在版本3上。它也適用於版本3嗎? – Aris

+0

編輯我的答案 –

+0

他使用v3和你的答案的第二句話說:「_考慮你正在使用'react-router v4'_」 –

2

如果您想全局聆聽history對象,則必須自己創建並將其傳遞給Router。然後,你可以聽它的listen()方法:

// Use Router from react-router, not BrowserRouter. 
import { Router } from 'react-router'; 

// Create history object. 
import createHistory from 'history/createBrowserHistory'; 
const history = createHistory(); 

// Listen to history changes. 
// You can unlisten by calling the constant (`unlisten()`). 
const unlisten = history.listen((location, action) => { 
    console.log(action, location.pathname, location.state); 
}); 

// Pass history to Router. 
<Router history={history}> 
    ... 
</Router> 

更妙的是,如果你創建歷史記錄對象作爲一個模塊,這樣你就可以隨時隨地輕鬆導入它,你可能需要它(如import history from './history';