【问题标题】:Should I use react-router for a tabs component?我应该将 react-router 用于选项卡组件吗?
【发布时间】:2017-07-18 15:43:56
【问题描述】:

我正在寻找构建一个选项卡组件,其中一些选项卡将包含动态内容。我最初开始遵循本教程:

Creating a tabs component with React

在阅读了 react-router 之后,似乎它也可以解决这个问题。什么是更好的方法和/或有什么不同?

【问题讨论】:

    标签: javascript reactjs tabs react-router


    【解决方案1】:

    是的,这是React Router 的完美工作,因为它专注于简化单页应用程序的 URL 重定向过程。

    导航选项卡的用例,绝对属于 React Router 的范围。您可以为此使用 React Router 3 或 4,但 React Router 4 API is on the horizon 和文档看起来很棒。

    您可以在上面的链接中找到一个有用的示例,它显示了与标签链接是多么容易。 here is an example 讨论了如何使用自定义链接创建选项卡。

    您可能需要考虑的“陷阱”之一是,如果您导航到不同的路线并且然后导航回上一条路线。这是一个进一步讨论此问题的线程:https://github.com/ReactTraining/react-router/issues/1686

    如果恢复滚动位置对你来说非常重要,那么此时 React Router 可能不是最适合标签的。

    更新:

    React router v4 已经发布,上面的问题已经解决,现在文档有how to restore scroll position的指南!

    【讨论】:

    • react-router 在跨标签视图导航时会破坏组件吗?如果我在每个选项卡上都有动态内容,我不想每次切换选项卡时都重新加载它
    • @Mirko 当另一个路由匹配时,被加载的组件卸载。
    • 示例链接不再有效,只会将您带到培训页面。
    • @apaidnerd 感谢您指出这一点!我刚刚更新了上面的链接:)
    【解决方案2】:

    我在设置它时遇到了很多问题(2017 年 11 月 20 日),我想我会在此处发布最终设置以供后代使用。我正在使用react-router-dom 4.2.2material-ui 0.19.4。基本上,您希望在用户单击选项卡时更改哈希 (#),并使用哈希来查找要显示的选项卡。它工作得很好,但不幸的是它增加了一点延迟,不知道为什么,如果我弄明白了会更新。

    import React, { Component } from 'react';
    import { Tabs, Tab } from 'material-ui/Tabs';
    
    export default class TabsComponent extends Component {
        constructor(props) {
            super(props);
            this.onActive = this.onActive.bind(this);
            this.getDefaultActiveTab = this.getDefaultActiveTab.bind(this);
    
            this.tabIndices = {
                '#firsttab': 0,
                '#secondtab': 1
            };
        }
        onActive(tab) {
            const tabName = tab.props.label.toLowerCase();
            this.props.history.replace(`#${tabName}`); // https://reacttraining.com/react-router/web/api/history
        }
        getDefaultActiveTab() {
            const hash = this.props.location.hash;
            return this.tabIndices[hash];
        }
        render() {
            return (
                <Tabs
                    initialSelectedIndex={this.getDefaultActiveTab()}
                >
                    <Tab
                        label="FirstTab"
                        onActive={this.onActive}
                    >
                       // ...
                    </Tab>
                    <Tab
                        label="SecondTab"
                        onActive={this.onActive}
                    >
                       // ...
                    </Tab>
                </Tabs>
            );
        }
    }
    

    还有...material-ui ^1.0.0-beta.26

    import React, { Component } from 'react';
    
    import Tabs, { Tab } from 'material-ui/Tabs';
    import Paper from 'material-ui/Paper';
    
    import { withRouter } from 'react-router-dom';
    
    import Resources from '../resources/index.jsx';
    import styled from 'styled-components';
    
    const StyledTabs = styled(Tabs) `
    margin:5px;
    `;
    
    class LinkableTabs extends Component {
        constructor(props) {
            super(props);
            this.getDefaultActiveTab = this.getDefaultActiveTab.bind(this);
            this.switchTab = this.switchTab.bind(this);
    
            this.state = {
                activeTabIndex: this.getDefaultActiveTab()
            }
        }
        getDefaultActiveTab() {
            const hash = this.props.location.hash;
    
            let initTabIndex = 0;
            this.props.tabs.forEach((x, i) => {
                const label = x.label;
                if (`#${label.toLowerCase()}` === hash) initTabIndex = i;
            });
    
            return initTabIndex;
        }
    
        switchTab(event, activeTabIndex) {
            this.setState({ activeTabIndex });
    
            //make shareable - modify URL
            const tabName = this.props.tabs[activeTabIndex].label.toLowerCase();
            this.props.history.replace(`#${tabName}`);
        }
        render() {
            const { match, location, history, staticContext, ...nonrouterProps } = this.props; //https://github.com/DefinitelyTyped/DefinitelyTyped/issues/13689#issuecomment-296246134
            const isScrollable = this.props.tabs.length > 2;
            return (
                <div>
                    <Paper>
                        <StyledTabs
                            fullWidth
                            centered
                            scrollable={isScrollable}
                            onChange={this.switchTab}
                            value={this.state.activeTabIndex}
                            {...nonrouterProps}
                        >
                            {
                                this.props.tabs.map(x => <Tab key={x.label} label={x.label} />)
                            }
                        </StyledTabs>
                    </Paper>
                    {
                        this.props.tabs[this.state.activeTabIndex].component
                    }
                </div>
            );
        }
    }
    
    export default withRouter(LinkableTabs);
    

    【讨论】:

      猜你喜欢
      • 2021-12-15
      • 2021-12-08
      • 2018-02-25
      • 1970-01-01
      • 1970-01-01
      • 2018-08-26
      • 2021-05-12
      • 2020-08-13
      • 2021-09-16
      相关资源
      最近更新 更多