我正在尝试将react-router v4,react和redux结合起来。因为react-router跟踪URL,我选择将该状态保留在redux-model之外。
但是当react-router发生路由更改时,我仍然需要一种方法来调度redux动作。哪个地方最好?
我的第一次尝试是将它放在react-router的链接的onClick属性中:
render() {
// link config
const links = this.props.photo.album( album => {
<Link key={album.name}
to=`/album/${album.name}`
onClick={() => this.props.dispatchAction(album.name)} />
})
// route config
return (
<div>
{links}
<Route path={`/album/:albumName`} component={Album}/>
</div>
)
}
这个想法是,当用户点击链接时,dispatchAction()将更新redux状态,然后加载Album组件。
问题在于,如果用户直接导航到URL(例如/ album / a1),则永远不会调度该操作,因为从技术上讲,该链接从未被点击过。
因此我删除了链接的onClick部分,并将dispatchAction移动到了Album组件的生命周期方法:
class Album extends Component {
// invoked when user navigates to /album/:albumName directly
componentDidMount() {
this.props.dispatchAction(this.props.match.params.albumName)
}
// invoked whenever the route changes after component mounted
componentWillReceiveProps(nextProps) {
if (this.props.match.params.albumName != nextProps.match.params.albumName) {
this.props.dispatchAction(nextProps.match.params.albumName)
}
....
}
现在,无论何时挂载Album组件或更改其属性,它都会调度redux-action。这是组合这些库的正确方法吗?
答案 0 :(得分:0)
react-router-redux通过在您的商店中应用中间件来为您执行此操作,该中间件调度路由更改的操作,也适用于初始路由更改。这绝对是最干净的方法。
唯一的缺点是它仍然是alpha,但我们一直在使用它而没有任何问题。它也是react-router
附加软件包repo的一部分。
答案 1 :(得分:0)
您可以创建一个自定义Route
组件,在componentDidMount
中调度您的操作:
class ActionRoute extends React.Component {
componentDidMount() {
const { pathname } = new URL(window.location.href);
const [albumName] = pathname.split('/').slice(-1);
this.props.dispatchAction(albumName);
}
render() {
return <Route {...this.props} />
}
}
现在,只要加载路线,就会调度您的操作。可组合性FTW!。
附注:如果您使用ActionRoute
作为参数化路线(例如/album/1
和/album/2
),您还需要在componentDidUpdate
中调度该行动作为如果您从/album/1
导航到/album/2
,则不会卸载/重新安装组件。