React Router v4中的嵌套路由未按预期渲染

3

我花了几天的时间尝试让我的嵌套路由起作用,但是我必须说我完全迷失了。

我正在尝试实现以下功能:

  1. 侧边栏有几个链接,其中一个链接指向 /banking。
  2. /banking 默认在 { CardWrapper } 中渲染组件 { BankingCards }
  3. 当用户单击 { BankingCards } 渲染的 4 张卡片之一的 <Link> 时,我希望在同一个 { 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>
    </>
  ); 
};

打印 console.log(match.params); 是什么意思? - Olivier Boissé
一个空对象。那时我意识到我做错了什么。 - user9522812
一个解决方案可以是使用 render 属性而不是 component,你可以在其中执行你的 switch case。 - Olivier Boissé
2个回答

6

更新:在深入网站研究后,找到了解决方案。

我的代码存在以下三个问题:

  1. I should have used render prop instead of component for the dynamic 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. Also, the dynamic route should have come before the /banking one. This is because the Switch statement will only render the first match. /banking was already a partial match, so the router wasn't reaching the nested routes like /banking/add-bank.

  3. The parent route, /banking, had the exact prop set to true. I now know that when using nested routes the parent route should not have exact enabled.

    class MainArea extends Component {
      state = {};
    
      render() {
        return (
          <div className={classes.MainArea}>
            <Route path="/banking" component={Banking} />
            <Route exact path="/planner" component={Planner} />
            <Route exact path="/notes" component={Notes} />
          </div>
        );
      }
    }
    

0

你可以使用渲染函数来修复你的例子。你之所以出错是因为在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="/"/>
    }
}}/>

谢谢你的建议,Olivier。我试了一下,但还是不行。我在渲染时记录了actionTypeComponent,但仍然没有任何显示。就像之前一样,我可以看到它将我带到了网址/banking/add-bank,但是<Banking />组件根本没有呈现。也就是说,甚至<h1>Banking</h1>标题都没有显示。我至少希望它能呈现出来,但不是<CardWrapper /> - user9522812
如果“Banking”未显示,则问题与负责显示“Banking”组件的路由有关,您能否向我们展示代码? - Olivier Boissé
你的两个建议都是正确的。我现在已经发布了更新。 - user9522812

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接