根据动作react更新 url

IT技术 reactjs react-router
2021-04-30 16:55:22

我是 ReactJS 的新手。我对 React Router v4 有问题,需要你们的一些建议。在我的应用程序 (React + Redux) 中,我正在配置我的路由:

/app/:appId/detail
/app/:appId/config/:store
/app/:appId/gifts

并同时渲染 2 个组件。一个选择组件(允许更改appId)和一个主要组件(显示数据)。

假设我在/app/1/detail 中,appId 为 1 并显示来自应用程序 1 的详细信息。当我按更改应用程序到 2 时,我想更改我的 url,如/app/2/detail并将数据更改为应用程序2 到时候。(意味着匹配 :appId 到 2)

我知道我可以使用 Redux 调度一个动作,然后DetailComponent(或ConfigComponent / GiftsComponent)可以捕获它并使用history.push 或 history.replace从组件内部(每个组件)更改手册我的应用程序有很多组件,手动处理会增加我的应用程序的复杂性,因此这不是解决它的好方法。

如果有任何解决方案,请帮助我。非常感谢你。

2个回答

所以你提到

一个选择组件(允许更改 appId)和一个主要组件(显示数据)。

并说明您担心以下问题:

我的应用程序有很多组件,手动处理会增加我的应用程序的复杂性,因此这不是解决它的好方法。

所以也许你应该withRouter首先HOC包装这个选择组件,因为它已经提到过,如果这个选择组件被使用不止一次。

包装将允许您访问以下props =>

props: { match, location, history }

match对象还包含paramsurlUrl 存储当前路径的值。在你的情况下,它基本上是/app/1/detail. Params 存储路由具有的参数。在您的情况下,参数将如下所示 params { appId: 1 }访问这些props将允许您在单个组件内实现和维护路由逻辑。

因此,如果您使用下拉菜单,您可以执行以下操作

import React from 'react';
import { Link, withRouter } from 'react-router-dom'

const SelectComponent = ({match: {params, url}}) => (
  <div>
    dropDownItems.map(item => 
       <Link 
        key={item.id // or simply item.appId}
        to={url.replace(`${params.appId}`, `item.appId`)
       >
        Change application to {item.appId}
      </Link>
    </div>
)

export default withRouter(SelectComponent)

由于params.appId对应于 '1' 并且我假设不会有任何参数等于 的值 appIdurl.replace(...) 因此基本上会用appIdurl 中的新值替换前者的值。

因此,任何更改都应将您重定向到更新后的新路线 appId

如果你使用按钮,你也可以<Link />用来包装你的按钮,但你也可以使用history.push方法作为onClick事件来处理重定向。

虽然您的问题不清楚,但您似乎想使用 react-router 以编程方式更改当前 url。

为此,您将需要来自 react-routerwithRouter HOC。有了它,你可以做这样的事情:

import React from 'react';
import PropTypes from 'prop-types';
import {withRouter} from 'react-router';

const ExampleComponent = (props) => {

  const goToNextId = () => {
    props.history.push(`/app/${props.match.params.appId + 1}/detail`);
  };

  return (
    <div>
      <button onClick={goToNextId}>Next Id</button>
    </div>
  );
};

ExampleComponent.propTypes = {
  history: PropTypes.object.isRequired,
  match: PropTypes.object.isRequired,
};

export default withRouter(ExampleComponent);