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

时间:2018-10-24 04:37:07

标签: reactjs react-router-v4 react-router-dom

所以我认为这个问题已经被问过几次了,但不确定是否被适当地问了。这就是我要经历的-我的路线如下:

<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 
}

这种创建的体验是用户浏览提案列表,然后接受或拒绝提案。用户可以在此父级ProductProposalView中与之交互的提议有两种(ServiceProposalViewReviewProposalView)。根据我们正在处理的提案类型,将呈现适当的视图。

每次对投标进行接受或拒绝确认时,我都希望将用户重定向到队列中的下一个投标,并在浏览器历史记录堆栈中推送新的URL,这样我就可以免费获得“返回”按钮的行为。

因此,如果我们从https://myreactapp.com/proposal/id1开始,我的ReviewProposalView会经历整个生命周期,最后毫无问题地到达componentDidMount。我的愿望是,当用户确认提案并通过https://myreactapp.com/proposal/id2重定向到<Redirect />时,我希望组件的整个生命周期从头开始重复并贯穿逻辑再次在componentDidMount中使用-实质上通过新的实例/开始来增强不变性。

我目前无法完成此操作,因为在您点击第二个URL时ReviewProposalView已被挂载。我的直觉告诉我,我如何构造组件是错误的,并且当它们与<Route />结合使用时,我从根本上误解了React组件生命周期。任何指导都值得赞赏。

2 个答案:

答案 0 :(得分:0)

嗨,我也是React.js的新手,但我了解您的问题,我已经遇到过同样的情况。

实际上,如果您是第一次去那条路线,那么ComponentDidMount将会调用,并且在您的情况下,您不是在更改路线,而是在更改查询参数。因此ComponentDidMount将不会被调用。

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

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

答案 1 :(得分:0)

尝试添加密钥以进行路由

current_tags

更改类型时,旧的Component卸载并作出反应将安装新的Component。因此,ReviewProposalView的生命周期重新开始。