如何使用 React 路由器 v4 处理重定向到同一路由(使用查询参数)



所以我认为这个问题已经被问了几次,但不确定它是否被问得合适。这是我正在经历的 - 我有一条路线如下:

<Route exact path={RoutePaths.PROPOSAL_ID} component={ReviewProposalView} />

RoutePaths.PROPOSAL_ID的价值是/proposal/:id

ReviewProposalView内部,我有以下componentDidMount()render()方法:

class ReviewProposalView extends Component<Props, State> {
state = {
redirect: false,
redirectTo: '',
currentProposalIdIndex: // whatever current value,
proposalIds: this.props.location.state.proposalIds,
proposalMap: this.props.location.state.proposalMap,
currentProposal: null
}
componentDidMount () {
const {location} = this.props
parseValueFromKeyInQueryString({queryString: location.search, key: 't'}, {
noValueFound: () => {
this.setState({
redirect: true,
redirectTo: RoutePaths.NOT_FOUND
})
},
valueFound: (type: string) => {
const {proposalMap} = this.state
const proposalId = // ...assume we got this from pathname
this.setState({
currentProposal: proposalMap[proposalId]
})
}
})
}
_confirmMatch = (confirmedProposal: Proposal) => {
// store data on confirmedProposal
// get next proposalId from this.state.proposalIds list
const nextProposal = proposalMap[nextProposalId]
this.setState({        
redirect: true,
redirectTo: {
pathname: `${RoutePaths.PROPOSAL}/${nextProposal.id}`,
search: `?t=${nextProposal.type}`,
state: {
currentProposalIdIndex: nextProposalIndex,
proposalIds,
proposalMap
}
}
})
}
render () {
const {currentProposal, redirect, redirectTo} = this.state
if (redirect) {
return <Redirect push to={redirectTo} />
}
const ProposalComponent = ProposalComponentMap[currentProposal.type]
return (
<div>
<h1>Review Proposals Page</h1>
<ProposalComponent {...this.props} key={currentProposal.id} proposal={currentProposal}
confirmProposal={this._confirmProposal} />
</div>
)
}
}
// ====================================
const ProposalComponentMap = {
'PRODUCT': ProductProposalView
'SERVICE': ServiceProposalView 
}

由此产生的体验是用户浏览建议列表,并将接受或拒绝建议。有两种不同类型的提案(ProductProposalViewServiceProposalView(,用户可以在此父ReviewProposalView中与之交互。根据我们正在处理的提案类型呈现适当的视图。

每次对提案进行接受或拒绝确认时,我都希望将用户重定向到队列中的下一个提案,并在浏览器历史记录堆栈中推送新 URL,以便我可以免费获取"后退"按钮行为。

因此,如果我们从https://myreactapp.com/proposal/id1开始,我的ReviewProposalView贯穿整个生命周期,最终达到componentDidMount没有问题。我的愿望是,当用户由于确认提案并通过<Redirect />重定向而进入https://myreactapp.com/proposal/id2时,我希望组件的整个生命周期从头开始重复,并再次运行componentDidMount中的逻辑 - 本质上是通过新的实例/启动来促进不变性的特征。

我目前拥有的无法做到这一点,因为当您点击第二个 URL 时,ReviewProposalView已经挂载。我的直觉告诉我,我构建组件的方式是错误的,当它们与 React 组件结合使用时,我从根本上误解了它们与<Route />的生命周期。任何和所有的指导都非常感谢。

嗨,我也是 React 的新手.js但我理解你的问题,我已经经历过同样的事情。

实际上,如果您第一次转到该路由,ComponentDidMount 将调用,在您的情况下,您不是在更改路由而是更改查询参数。因此,不会调用 ComponentDidMount。

在这种情况下,您可以尝试使用componentWillReceiveProps而不是ComponentDidMount。

这将导致重新渲染组件。您需要处理道具的特定更改。 这个例子将帮助您使用componentWillReceiveProps 钩。https://stackoverflow.com/a/32414771/1506955

尝试添加键到路由,例如

<Route key={type} exact path={RoutePaths.PROPOSAL_ID} component={ReviewProposalView}/>

当类型更改时,旧组件卸载并反应将挂载新组件。因此,ReviewProposalView的生命周期重新开始。

最新更新