我有一个使用redux和react-router的通用反应应用程序。
我有以下几条路线:
/2016
/2015
/2014
/2013
等
每条路线都需要来自API的数据。目前,我在导航组件中有<Link>
个元素调度异步操作onClick
,该操作使用来自该路由的API的数据填充商店。
对于MVP,我只是在路由更改时用新帖子内容覆盖商店中的post: {}
内容,这样我们就可以获得API上的任何新内容。
我已经意识到在<Link>
按钮上设置操作调度程序并不是最佳选择,因为按下后退按钮不会重新触发操作调度以获取上一个路由的内容。
有没有办法让React Router在路由发生变化时随时触发调度操作? (限制它听一组特定的路线将是一个奖励)。
我意识到我应该从商店获取历史记录,但就目前而言,通过触发行动调度以获取新内容,再次点击API会更容易。< / em>的
干杯。
答案 0 :(得分:11)
React-router 4中已删除了“生命周期”钩子onEnter
和onChange
,这使该问题的大多数其他答案都已过时。
虽然我建议您使用组件生命周期方法实现目标,但这是您的问题的答案,该问题适用于React-router 4。
今天有效的方法是使用由React路由器的开发人员自己创建的History library来监听历史更改,并从那里调度异步操作。
// history.js
import createHistory from "history/createBrowserHistory"
const history = createHistory()
// Get the current location.
const location = history.location
// Listen for changes to the current location.
const unlisten = history.listen((location, action) => {
//Do your logic here and dispatch if needed
})
export default history
然后将历史记录导入到您的应用程序中
// App.js
import { Router, Route } from 'react-router-dom';
import Home from './components/Home';
import Login from './components/Login';
import history from './history';
class App extends Component {
render() {
return (
<Router history={history}>
<div>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
</div>
</Router>
)
}
}
答案 1 :(得分:8)
是的React路由器有onEnter和onLeave挂钩。您可以构建路由以获取store
实例,以便可以在这些帮助程序中访问它:
const createRoutes = (store) => {
const fetchPosts = () => store.dispatch({
types: ['FETCH_POSTS', 'FETCH_POSTS_SUCCESS', 'FETCH_POSTS_FAIL',
url: '/posts'
});
return (
<Route path="/" component={App}>
<Route path="posts" component={PostList} onEnter={fetchPosts}/>
<Route path="posts/:id" component={PostDetail} />
</Route>
)
}
更好的解决方案是使用redial
或redux-async-connect
之类的内容。这允许您将组件的数据依赖性与组件共同定位,同时保留在不触及网络的情况下测试组件的能力。
修改:这适用于旧的,不再受支持的react-router
版本。
答案 2 :(得分:1)
我更喜欢从渲染道具本身分派动作:
<Route to="path" render={ props => {
this.props.toggleInfoLayer(true);
return <UserInfo />;
}} />
这是假设您正在使用Redux的mapDispatchToProps
参数。
我尝试使用接受的答案中提到的历史记录更改事件处理程序,但是我发现不希望从恶意文件中分派动作。当Redux已经提供了太多的东西时,我不得不考虑的另一个地方。