ルートとして機能するボタンがいくつかあります。経路が変更されるたびに、アクティブなボタンが変更されていることを確認したいです。
反応ルータv4で経路変更を監視する方法はありますか?
私はwithRouter
を使用してlocation
プロップを取得します。新しいルートのためにコンポーネントが更新されると、値が変更されたかどうかを確認します。
@withRouter
class App extends React.Component {
static propTypes = {
location: React.PropTypes.object.isRequired
}
// ...
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
this.onRouteChanged();
}
}
onRouteChanged() {
console.log("ROUTE CHANGED");
}
// ...
render(){
return <Switch>
<Route path="/" exact component={HomePage} />
<Route path="/checkout" component={CheckoutPage} />
<Route path="/success" component={SuccessPage} />
// ...
<Route component={NotFound} />
</Switch>
}
}
それが役に立てば幸い
上記をさらに拡張するには、履歴オブジェクトにアクセスする必要があります。 BrowserRouter
を使用している場合は、withRouter
をインポートし、コンポーネントを 高次コンポーネント(HoC) でラップして、履歴オブジェクトのプロパティと機能。
import { withRouter } from 'react-router-dom';
const myComponent = ({ history }) => {
history.listen((location, action) => {
// location is an object like window.location
console.log(action, location.pathname, location.state)
});
return <div>...</div>;
};
export default withRouter(myComponent);
気を付けなければいけないことは、withRouterや他のほとんどのhistory
へのアクセス方法は、オブジェクトをそれに分解するときにプロップを汚染するように見えるということです。
あなたは history v4 libを使うべきです。
そこからの例
history.listen((location, action) => {
console.log(`The current URL is ${location.pathname}${location.search}${location.hash}`)
console.log(`The last navigation action was ${action}`)
})
フック付き:
import { useEffect } from 'react'
import { withRouter } from 'react-router-dom'
import { history as historyShape } from 'react-router-prop-types'
const DebugHistory = ({ history }) => {
useEffect(() => {
console.log('> Router', history.action, history.location])
}, [history.location.key])
return null
}
DebugHistory.propTypes = { history: historyShape }
export default withRouter(DebugHistory)
<DebugHistory>
コンポーネントとしてインポートしてレンダリングする
withRouter
、history.listen
、およびuseEffect
(React Hooks)は非常にうまく機能します。
const Component = ({ history }) => {
useEffect(() => history.listen(() => {
// do something on route change
// for my example, close a drawer
}), [])
//...
}
export default withRouter(Component)
リスナーコールバックは、ルートが変更されるたびに起動し、history.listen
の戻り値は、useEffect
とうまく機能するシャットダウンハンドラーです。
場合によっては、次のようにrender
ではなくcomponent
属性を使用することがあります。
class App extends React.Component {
constructor (props) {
super(props);
}
onRouteChange (pageId) {
console.log(pageId);
}
render () {
return <Switch>
<Route path="/" exact render={(props) => {
this.onRouteChange('home');
return <HomePage {...props} />;
}} />
<Route path="/checkout" exact render={(props) => {
this.onRouteChange('checkout');
return <CheckoutPage {...props} />;
}} />
</Switch>
}
}
onRouteChange
メソッドで状態を変更すると、「最大更新深度を超えました」というエラーが発生する可能性があることに注意してください。