我需要检测是否发生了路由更改,以便可以将变量更改为true。
我已经仔细研究了以下问题:
1. https://github.com/ReactTraining/react-router/issues/3554
2. How to listen to route changes in react router v4?
3. Detect Route Change with react-router
他们都没有为我工作。发生路线更改时,有没有一种清晰的方法来调用函数。
答案 0 :(得分:15)
一种方法是使用withRouter
高阶组件。
Live demo (单击超链接以更改路线并在显示的控制台中查看结果)
您可以通过withRouter高阶组件访问历史对象的属性和最接近的匹配项。每当呈现时,withRouter都会将更新的匹配项,位置和历史道具传递给包装的组件。
import {withRouter} from 'react-router-dom';
class App extends Component {
componentDidUpdate(prevProps) {
if (this.props.location.pathname !== prevProps.location.pathname) {
console.log('Route change!');
}
}
render() {
return (
<div className="App">
...routes
</div>
);
}
}
export default withRouter(props => <App {...props}/>);
另一个使用url参数的示例:
如果您要将配置文件路由从/profile/20
更改为/profile/32
您的路线被定义为/profile/:userId
componentDidUpdate(prevProps) {
if (this.props.match.params.userId !== prevProps.match.params.userId) {
console.log('Route change!');
}
}
答案 1 :(得分:8)
使用React Hooks,它应该很简单:
useEffect(() => {
const { pathname } = location;
console.log('New path:', pathname);
}, [location.pathname]);
通过在第二个数组参数中传递location.pathname
,意味着您要说使用useEffect仅在location.pathname
更改时重新运行。
带有代码源:https://codesandbox.io/s/detect-route-path-changes-with-react-hooks-dt16i
的实时示例答案 2 :(得分:3)
React Router v5现在通过钩子自动检测路由更改。以下是the example from the team:
import { Switch, useLocation } from 'react-router'
function usePageViews() {
let location = useLocation()
useEffect(
() => {
ga.send(['pageview', location.pathname])
},
[location]
)
}
function App() {
usePageViews()
return <Switch>{/* your routes here */}</Switch>
}
每次URL更改时,此示例都会向Google Analytics(分析)(ga
)发送“页面视图”。
答案 3 :(得分:0)
答案 4 :(得分:0)
使用基于组件的体系结构。那么,为什么我们不遵守这个规则?
您可以看到DEMO。
每个页面必须由HOC包装,这将自动检测页面的变化。
首页
import React from "react";
import { NavLink } from "react-router-dom";
import withBase from "./withBase";
const Home = () => (
<div>
<p>Welcome Home!!!</p>
<NavLink to="/login">Go to login page</NavLink>
</div>
);
export default withBase(Home);
withBase HOC
import React from "react";
export default WrappedComponent =>
class extends React.Component {
componentDidMount() {
this.props.handleChangePage();
}
render() {
return <WrappedComponent />;
}
};
答案 5 :(得分:0)
当组件被指定为<form>
<div>
<label for="file">Choose file to upload</label>
<input type="file" id={fileName} />
</div>
<div>
<!--Should be something along the lines of `this.handleSubmit`
rather than `this.print`, but you get the idea-->
<button onClick={this.print}>Submit</button>
</div>
</form>
的{{1}}属性时,React Router 4(RR4)向其传递了一些附加属性:<Route>
,component
和{{1 }}。
然后,您应该使用match
生命周期方法在更新前后比较location
个对象(记住ES对象比较规则)。由于位置对象是不可变的,因此它们将永远不会匹配。即使您导航到相同的位置。
history
需要在未指定为任何Route的componentDidUpdate
属性的任意组件中访问这些属性时,应使用 location
。请确保将您的应用包装在 componentDidUpdate(newProps) {
if (this.props.location !== newProps.location) {
this.handleNavigation();
}
}
中,因为它提供了所有必需的API,否则这些方法将仅在withRouter
中包含的组件中起作用。
在某些情况下,用户决定通过导航按钮而不是浏览器中的专用界面来重新加载页面。但是这样的比较:
component
将使其变为不可能。