React Router v4 中的嵌套路由未按预期呈现
Nested routes in React Router v4 not rendering as expected
过去几天我一直在努力让我的嵌套路线发挥作用,我不得不说我完全迷路了。
我正在尝试使用以下功能:
- 带有多个链接的边栏。其中之一导致 /banking.
- /banking 默认在
{ CardWrapper }
. 中呈现组件 { BankingCards }
- 当用户点击由
{ BankingCards }
呈现的 4 张卡片之一的 <Link>
时,我想在同一个 { CardWrapper }
.[=32= 中呈现嵌套路径]
在下面的代码块中,您会注意到我尝试使用 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>
</>
);
};
您可以使用 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="/"/>
}
}}/>
更新:在网站上深入挖掘后找到了解决方案
我的代码有 3 个问题:
我应该使用 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>
此外,动态路由应该在 /banking
之前。这是因为 Switch
语句只会呈现第一个匹配项。 /banking
已经部分匹配,因此路由器没有到达 /banking/add-bank
.
这样的嵌套路由
父路由 /banking
的 exact
属性设置为 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>
);
}
}
过去几天我一直在努力让我的嵌套路线发挥作用,我不得不说我完全迷路了。
我正在尝试使用以下功能:
- 带有多个链接的边栏。其中之一导致 /banking.
- /banking 默认在
{ CardWrapper }
. 中呈现组件 - 当用户点击由
{ BankingCards }
呈现的 4 张卡片之一的<Link>
时,我想在同一个{ CardWrapper }
.[=32= 中呈现嵌套路径]
{ BankingCards }
在下面的代码块中,您会注意到我尝试使用 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>
</>
);
};
您可以使用 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="/"/>
}
}}/>
更新:在网站上深入挖掘后找到了解决方案
我的代码有 3 个问题:
我应该使用
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>
此外,动态路由应该在
/banking
之前。这是因为Switch
语句只会呈现第一个匹配项。/banking
已经部分匹配,因此路由器没有到达/banking/add-bank
. 这样的嵌套路由
父路由
/banking
的exact
属性设置为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> ); } }