2017-02-27 18 views
5

いくつかのタブに動的コンテンツが含まれるタブコンポーネントをビルドしようとしています。私はもともと、このチュートリアルに従うことを開始しました:タブコンポーネントに反応ルータを使用する必要がありますか?

Creating a tabs component with React

反応し、ルータ上に読んだ後、のは、それはまた、この問題を解決することができように見えます。より良いアプローチとは何か、そして/またはそれは何を変えるのでしょうか?

答えて

6

はい、これはのための完璧な仕事です。これは、単一ページアプリケーションのURLリダイレクトプロセスを簡略化することに重点を置いているので、これはです。

ナビゲーション用のタブの使用例は、間違いなくリアクタの範囲に該当します。あなたはこれにReact Router 3または4を使うことができますが、React Router 4 API is on the horizonとドキュメントはすばらしく見えます。

上記のリンクにという便利な例のが表示され、タブとのリンクが簡単に表示されます。カスタムリンクを使用してタブを作成する方法については、here is an exampleを参照してください。あなたが考慮したいかもしれないけれども

の一つ「の落とし穴」、あなたは別のルートに移動し、以前のルートに戻って移動した場合、スクロール位置を復元するいくつかの困難があったことです。この問題をさらに詳しく解説するスレッドは、https://github.com/ReactTraining/react-router/issues/1686です。

スクロール位置を復元することが非常に重要な場合は、この時点でリアクションルーターがタブに最適でない可能性があります。

+1

'反応-router'んタブのビュー間でナビゲートするときにコンポーネントを破壊しますか?各タブに動的なコンテンツがある場合は、タブを切り替えるたびにリロードしたくないです。 – Mirko

+1

@Mirko別のルートが一致すると、読み込まれたコンポーネントがアンマウントされます。 – protoEvangelion

2

私はこれを設定することに多くの問題がありました(2017年11月20日)、後世のためにここに最終的な設定を投稿すると思いました。私はreact-router-dom 4.2.2material-ui 0.19.4を使用しています。 Basciallyでは、ユーザーがタブをクリックしたときにハッシュ(#)を変更し、そのタブを表示するためにハッシュを使用します。それはかなりうまくいきますが、残念ながらそれは少し遅れてしまいます。なぜそれが分かったら、なぜ更新されるのかわかりません。

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); 
関連する問題