React Router v4中的嵌套路由未按预期呈现

时间:2019-01-01 22:24:48

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

过去的几天我一直在努力使嵌套的路线正常工作,我不得不说我完全迷路了。

我正在尝试使用以下功能:

  1. 带有几个链接的侧边栏。其中之一导致/ banking。
  2. /默认情况下,银行业务在{ BankingCards }内呈现组件{ CardWrapper }
  3. 当用户单击<Link>呈现的4张卡片之一中的{ BankingCards }时,我想在同一{ CardWrapper }内部呈现嵌套路径。

在下面的代码块中,您会注意到我尝试使用switch语句将组件动态分配给actionComponent。这似乎以多种方式破坏了功能。

这是错误的方法,还是我缺少有关React Router组件的信息?

// Banking.js

import CardWrapper from '../../Wrappers/CardWrapper/CardWrapper';
import BankingCards from './BankingCards/BankingCards';
import AddBank from './AddBank/AddBank';
import AddDebit from './AddDebit/AddDebit';
import AddCredit from './AddCredit/AddCredit';
import AddDirect from './AddDirect/AddDirect';

class Banking extends Component {
  state = {};

  render() {
    const { match } = this.props;
    console.log(match.params);
    // let actionComponent;
    // switch (match.params.actionType) { 
    //   case 'add-bank':
    //   actionComponent = AddBank;
    //     break;
    //   case 'add-debit':
    //   actionComponent = AddDebit;
    //     break;
    //   case 'add-credit':
    //   actionComponent = AddCredit;
    //     break;
    //   case 'add-direct':
    //   actionComponent = AddDirect;
    //     break;
    //   default:
    //     return null;
    // }
    return (
      <div className={classes.Banking}>
        <h1 className={classes.mainHeader}>Banking</h1>
        <CardWrapper>
          <Switch>
            <Route exact path={`${match.path}`} component={BankingCards} />
            <Route path={`${match.path}/:actionType`} component={actionComponent} /> 
          </Switch>
        </CardWrapper>
      </div>
    )
  }
}

// BankingCards.js

const bankingCards = ({ match }) => {

  return (
    <>
      <Card>
        <h1>Add Bank Account</h1>
        <Link to={`${match.url}/add-bank`}>
          <SVG src={iconPlus} className={classes.iconPlus} />
        </Link>
        <h3>Manage accounts</h3>
      </Card>

      <Card>
        <h1>Add Debit Card</h1>
        <Link to={`${match.url}/add-debit`}>
          <SVG src={iconPlus} className={classes.iconPlus} />
        </Link>
        <h3>Manage debit cards</h3>
      </Card>

      <Card>
        <h1>Add Credit Card</h1>
        <Link to={`${match.url}/add-credit`}>
          <SVG src={iconPlus} className={classes.iconPlus} />
        </Link>
        <h3>Manage credit cards</h3>
      </Card>

      <Card>
        <h1>Add Direct Debit</h1>
        <Link to={`${match.url}/add-direct`}>
          <SVG src={iconPlus} className={classes.iconPlus} />
        </Link>
        <h3>Manage direct debits</h3>
      </Card>
    </>
  ); 
};

2 个答案:

答案 0 :(得分:0)

您可以使用render function来解决您的示例。您有一个错误,因为在Banking组件math.params中没有actionType属性。

function getActionComponent(actionType) {
   switch (actionType) { 
     case 'add-bank':
       return AddBank;
     case 'add-debit':
       return AddDebit;
     case 'add-credit':
         return AddCredit;
     case 'add-direct':
        return AddDirect;
     default:
        return null;
}

<Route path={`${match.path}/:actionType`} render={props => {
    const actionType = props.match.params.actionType;
    const Component = getActionComponent(actionType);
    if (Component) {
       return <Component {...props}/>;
    } else {
       return <Redirect to="/"/>
    }
}}/>

答案 1 :(得分:0)

更新:在网站上进行了更深入的研究后找到了解决方案

我的代码存在3个问题:

  1. 对于动态render,我应该使用component道具而不是Route

    <Switch>
      <Route path={`${match.path}/:actionType`} render={props => {
        const actionType = props.match.params.actionType;
        const Component = getActionComponent(actionType);
        if (Component) {
          return <Component {...props} />;
        } else {
          return <Redirect to="/" />
        }
      }} /> 
      <Route path={`${match.path}`} component={BankingCards} />
    </Switch>
    
  2. 此外,动态路由应该早于/banking前。这是因为Switch语句将仅呈现第一个匹配项。 /banking已经是部分匹配,因此路由器无法到达/banking/add-bank之类的嵌套路由。

  3. 父路线/banking的{​​{1}}属性设置为exact。我现在知道,当使用嵌套路由时,父路由不应启用true

    exact