我有几个按钮作为路径。每次改变路线时,我都想确保激活的按钮发生了变化。
有没有办法在react路由器v4中监听路由变化?
我有几个按钮作为路径。每次改变路线时,我都想确保激活的按钮发生了变化。
有没有办法在react路由器v4中监听路由变化?
当前回答
我刚刚处理了这个问题,所以我将把我的解答作为其他答案的补充。
这里的问题是useEffect并没有像您希望的那样工作,因为调用只在第一次呈现之后才被触发,因此存在不必要的延迟。 如果您使用一些状态管理器,如redux,您很可能会在屏幕上看到闪烁,因为存储中存在持续的状态。
你真正想要的是使用uselayouteeffect,因为它会立即被触发。
所以我写了一个小的实用函数,我把它放在和路由器相同的目录中:
export const callApis = (fn, path) => {
useLayoutEffect(() => {
fn();
}, [path]);
};
我从组件HOC中调用它,如下所示:
callApis(() => getTopicById({topicId}), path);
path是使用withRouter时在match对象中传递的道具。
我真的不赞成手动地听/不听历史。 这只是我的看法。
其他回答
我使用withRouter来获取位置道具。当组件因为一个新的路由而更新时,我检查值是否发生了变化:
@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>
}
}
我刚刚处理了这个问题,所以我将把我的解答作为其他答案的补充。
这里的问题是useEffect并没有像您希望的那样工作,因为调用只在第一次呈现之后才被触发,因此存在不必要的延迟。 如果您使用一些状态管理器,如redux,您很可能会在屏幕上看到闪烁,因为存储中存在持续的状态。
你真正想要的是使用uselayouteeffect,因为它会立即被触发。
所以我写了一个小的实用函数,我把它放在和路由器相同的目录中:
export const callApis = (fn, path) => {
useLayoutEffect(() => {
fn();
}, [path]);
};
我从组件HOC中调用它,如下所示:
callApis(() => getTopicById({topicId}), path);
path是使用withRouter时在match对象中传递的道具。
我真的不赞成手动地听/不听历史。 这只是我的看法。
使用useEffect钩子,可以在不添加侦听器的情况下检测路由更改。
import React, { useEffect } from 'react';
import { Switch, Route, withRouter } from 'react-router-dom';
import Main from './Main';
import Blog from './Blog';
const App = ({history}) => {
useEffect( () => {
// When route changes, history.location.pathname changes as well
// And the code will execute after this line
}, [history.location.pathname]);
return (<Switch>
<Route exact path = '/' component = {Main}/>
<Route exact path = '/blog' component = {Blog}/>
</Switch>);
}
export default withRouter(App);
对于react Hooks,我使用useEffect
import React from 'react'
const history = useHistory()
const queryString = require('query-string')
const parsed = queryString.parse(location.search)
const [search, setSearch] = useState(parsed.search ? parsed.search : '')
useEffect(() => {
const parsedSearch = parsed.search ? parsed.search : ''
if (parsedSearch !== search) {
// do some action! The route Changed!
}
}, [location.search])
在这个例子中,当路由改变时,我向上滚动:
import React from 'react'
import { useLocation } from 'react-router-dom'
const ScrollToTop = () => {
const location = useLocation()
React.useEffect(() => {
window.scrollTo(0, 0)
}, [location.key])
return null
}
export default ScrollToTop
对于React路由器v6和React钩子, 你需要使用useLocation而不是useHistory,因为它已被弃用
import { useLocation } from 'react-router-dom'
import { useEffect } from 'react'
export default function Component() {
const history = useLocation();
useEffect(() => {
console.log('> Router', history.pathname)
}, [history.pathname]);
}