antd选项卡使用react-router

时间:2018-06-06 20:48:53

标签: reactjs react-router-v4 antd

想知道我们是否有办法根据每个标签的嵌套路线渲染路线。

例如,当我们浏览

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}}

2 个答案:

答案 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;