Вложенные маршруты в React Router v4 не отображаются должным образом - PullRequest
0 голосов
/ 02 января 2019

Последние несколько дней я пытался заставить работать мои вложенные маршруты, и я должен сказать, что я полностью потерян.

Я пытаюсь заставить работать следующие функции:

  1. Боковая панель с несколькими ссылками.Один из них приводит к /banking.
  2. / banking по умолчанию отображает компонент { 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 голосов
/ 02 января 2019

ОБНОВЛЕНИЕ: Нашел решение после более глубокого поиска на сайте

С моим кодом было 3 проблемы:

  1. Я должен был использоватьrender prop вместо 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, была exact propустановите на true.Теперь я знаю, что при использовании вложенных маршрутов родительский маршрут не должен включать exact.

    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 голосов
/ 02 января 2019

Вы можете использовать функцию рендеринга , чтобы исправить ваш пример.У вас есть ошибка, потому что в 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="/"/>
    }
}}/>
...