想知道我们是否有办法根据每个标签的嵌套路线渲染路线。
例如,当我们浏览
时tab
我们希望有一个nested route
组件,它提供了一种布局,并根据我们点击的<Route path={"/base:scope" } exact={true} { component: BaseComponent } />
应该呈现import { Layout, Tabs, Row, Col } from 'antd';
import { Link, NavLink, Route, Switch } from 'react-router-dom';
export class BaseComponent extends React.Component {
public state = {
collapsed: false,
};
private onCollapse = collapsed => {
this.setState({ collapsed });
}
get tabs() {
const { collaborators, integration, settings, configuration, billing, tokens, referrals } = this.props;
return [
{
key: 'a',
tab: 'a',
component: ComponentA,
path: '/base/a',
},
{
key: 'b',
tab: 'b',
component: ComponentB,
path: '/base/b',
},
];
}
public componentWillReceiveProps(props) {
if (!_.isEqual(_.get(this.props, 'match.url'), _.get(props, 'match.url'))) {
this.setState({ key: _.get(props, 'match.url') });
}
}
public render() {
const { renderer, router } = this.context;
const { onLogOut, match, user, profile } = this.props;
return (
<React.Fragment>
<Header className={renderer.renderRule(styles.header, this.props)}>
<div className={renderer.renderRule(styles.title, this.props)}>
Account Settings
</div>
</Header>
<Content>
<div className={renderer.renderRule(styles.container, this.props)}>
<Tabs
animated={false}
defaultActiveKey={match.url}
onChange={key => router.history.push(key)}
className={`${renderer.renderRule(styles.tabs)}`}
>
{_.map(this.tabs, (record, index) => (
<TabPane
key={record.path}
className={renderer.renderRule(styles.pane)}
tab={<span>{record.tab}</span>}
>
{React.createElement(record.component, null, null)}
</TabPane>
))}
</Tabs>
</div>
</Content>
</React.Fragment >
);
}
}
组件。
以下示例在不使用react-router渲染选项卡组件的情况下工作。
以下是路线配置
<Routes path={"/base"} exact={false} component={ComponentBase} />
<Routes path={"/base/a"} exact={true} component={ComponentBase} />
<Routes path={"/base/b"} exact={true} component={ComponentBase} />
以下组件将使用标签
呈现页面export class BaseComponent extends React.Component {
public state = {
collapsed: false,
};
private onCollapse = collapsed => {
this.setState({ collapsed });
}
get tabs() {
const { collaborators, integration, settings, configuration, billing, tokens, referrals } = this.props;
return [
{
key: 'a',
tab: 'a',
path: '/base/a',
},
{
key: 'b',
tab: 'b',
path: '/base/b',
},
];
}
public componentWillReceiveProps(props) {
if (!_.isEqual(_.get(this.props, 'match.url'), _.get(props, 'match.url'))) {
this.setState({ key: _.get(props, 'match.url') });
}
}
public render() {
const { renderer, router } = this.context;
const { onLogOut, match, user, profile } = this.props;
return (
<React.Fragment>
<Header className={renderer.renderRule(styles.header, this.props)}>
<div className={renderer.renderRule(styles.title, this.props)}>
Account Settings
</div>
</Header>
<Content>
<div className={renderer.renderRule(styles.container, this.props)}>
<Tabs
animated={false}
defaultActiveKey={match.url}
onChange={key => router.history.push(key)}
className={`${renderer.renderRule(styles.tabs)}`}
>
{_.map(this.tabs, (record, index) => (
<TabPane
key={record.path}
className={renderer.renderRule(styles.pane)}
tab={<span>{record.tab}</span>}
>
</TabPane>
))}
</Tabs>
</div>
</Content>
</React.Fragment >
);
}
}
期望:
我们希望编写更具反应性的路由器,如
{{1}}
但在这种情况下,我们不知道如何渲染页面,因为反应路由器不会重新页面,所以我们注意到标签但没有渲染内容。
这是没有渲染内容的修改组件,因为我们期望react-router渲染组件。
{{1}}
答案 0 :(得分:0)
如果您确定要使用路由器明确定义选项卡,则在组件中设置道具:
props.match.params
More info on Route from react router docs.
我认为最好使用react路由器提供的{{1}},而不是明确定义标签more info and example here。
您可以从{props.match.params.base}获取值并拉出该标签。
答案 1 :(得分:0)
我试图使用antd标签创建RoutedTabs组件。我已经为它添加了文档字符串。
import React from "react";
import PropTypes from "prop-types";
import { Tabs } from "antd";
import { Switch, Route } from "react-router-dom";
import _each from "lodash/each";
import _map from "lodash/map";
const { TabPane } = Tabs;
/**
* RoutedTabs is Ant Design based dynamic navigation tabs component.
* It takes router config as prop and render the component as well as update the window location corrosponding to the tab.
* Example of routeConfig
* overview: {
label: "Overview",
component: RestaurantOverview,
getRoute: url => url
},
menu: {
label: "Menu",
component: Menu,
getRoute: url => `${url}/menu`
},
"menu-holiday-slot": {
label: "Menu Holiday Slot",
component: MenuHolidaySlots,
getRoute: url => `${url}/menu-holiday-slot`
}
This will render three tabs Overview, Menu, Menu Holiday Slot and routes based on what getRoute method returns.
*/
const RoutedTabs = props => {
const { tabsProps, routeConfig } = props;
const { url, path } = props.match;
const tabToRouteMap = {};
const routeToTabsMap = {};
_each(routeConfig, (configObj, routeKey) => {
const routeURL = configObj.getRoute(url);
tabToRouteMap[routeKey] = routeURL;
routeToTabsMap[routeURL] = routeKey;
});
const defaultActiveKey = routeToTabsMap[props.history.location.pathname];
const tabPaneNodes = _map(routeConfig, (configObj, routeKey) => (
<TabPane tab={configObj.label} key={routeKey} />
));
const routeNodes = _map(routeConfig, (configObj, routeKey) => (
<Route
path={configObj.getRoute(path)}
exact
key={routeKey}
component={configObj.component}
/>
));
const onTabChange = activeKey => {
props.history.push(tabToRouteMap[activeKey]);
};
return (
<>
<Tabs {...tabsProps} onChange={onTabChange} defaultActiveKey={defaultActiveKey}>
{tabPaneNodes}
</Tabs>
<Switch>{routeNodes}</Switch>
</>
);
};
RoutedTabs.propTypes = {
tabsProps: PropTypes.object.isRequired, // As per https://ant.design/components/tabs/#Tabs
routeConfig: PropTypes.object.isRequired,
match: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
};
export default RoutedTabs;