2017-01-13 25 views
8

Nowa składnia rotuera używa komponentu Link do poruszania się po trasach. Ale w jaki sposób można to zintegrować z materiaul-ui?Integracja zakładek Material-UI z routerem reagowania 4?

W moim przypadku używam zakładek jako główny system nawigacji, więc teoretycznie powinienem mieć coś takiego:

const TabLink = ({ onClick, href, isActive, label }) => 
    <Tab 
    label={label} 
    onActive={onClick} 
    /> 



export default class NavBar extends React.Component { 
    render() { 
    return (
     <Tabs> 
     <Link to="/">{params => <TabLink label="Home" {...params}/>}</Link> 
     <Link to="/shop">{params => <TabLink label="shop" {...params}/>}</Link> 
     <Link to="/gallery">{params => <TabLink label="gallery" {...params}/>}</Link> 
     </Tabs> 
    ) 
    } 
} 

Ale kiedy to czyni, materiał-ui zgłasza błąd, że dziecko z Tabs musi być komponentem Tab. Jaki może być sposób postępowania? Jak zarządzać rekwizytem isActive dla karty?

góry dzięki

+0

odpowiedzi pełny tutaj - https://stackoverflow.com/a/47396910/4180797 –

Odpowiedz

4

Mój instruktor pomógł mi z użyciem React Ruter 4.0 za withRouter zawinąć zakładkach składnik włączyć metody historii tak:

import React, {Component} from "react"; 
import {Tabs, Tab} from 'material-ui'; 
import { withRouter } from "react-router-dom"; 

import Home from "./Home"; 
import Portfolio from "./Portfolio"; 

class NavTabs extends Component { 

handleCallToRouter = (value) => { 
    this.props.history.push(value); 
} 

    render() { 
    return (
     <Tabs 
     value={this.props.history.location.pathname} 
     onChange={this.handleCallToRouter} 
     > 
     <Tab 
      label="Home" 
      value="/" 
     > 
     <div> 
      <Home /> 
     </div> 
     </Tab> 
     <Tab 
      label="Portfolio" 
      value="/portfolio" 
      > 
      <div> 
      <Portfolio /> 
      </div> 
     </Tab> 
     </Tabs>   
    ) 
    } 
} 

export default withRouter(NavTabs) 

Wystarczy dodać BrowserRouter do index.js i jesteś dobry, aby przejść.

+0

Jest to dobre, ale ze względu na "wartość = {this.props.history.location.pathname} 'spowoduje to błąd:' 'Ostrzeżenie: Material-UI: podana wartość'/portfolio/123' jest nieprawidłowa'' jeśli dodasz routing do konkretnego elementu lub jakiejkolwiek trasy, która nie jest zdefiniowana w kartach. – Ogglas

1

Można używać browserHistory zamiast reagować-Router Link składnik

import { browserHistory } from 'react-router' 

// Go to /some/path. 
onClick(label) { 
    browserHistory.push('/${label}'); 
} 

// Example for Go back 
//browserHistory.goBack() 

<Tabs> 
    <Tab 
    label={label} 
    onActive={() => onClick(label)} 
    /> 
</Tabs> 

Jak widać można po prostu push() twój cel do browserHistory

+0

W wersji 4 nie ma żadnych "browserHistory", spójrz na ich [index.js] (https://github.com/ReactTraining/react-router/blob/v4/packages/react-router -dom/modules/index.js). –

+0

Jest coś podobnego w przekazywanych rekwizytach 'props.push (url, state)' – JustGoscha

2

błąd Obserwujemy z material-ui jest, ponieważ oczekuje się, że komponent <Tab> będzie renderowany jako element potomny składnika <Tabs>.

Teraz tutaj jest sposób, że mam znaleźć zintegrować link do komponentu <Tabs> bez utraty style:

import React, {Component} from 'react'; 
import {Tabs, Tab} from 'material-ui/Tabs'; 
import {Link} from 'react-router-dom'; 

export default class MyComponent extends Component { 
    render() { 
     const {location} = this.props; 
     const {pathname} = location; 

     return (
      <Tabs value={pathname}> 
       <Tab label="First tab" containerElement={<Link to="/my-firs-tab-view" />} value="/my-firs-tab-view"> 
        {/* insert your component to be rendered inside the tab here */} 
       </Tab> 
       <Tab label="Second tab" containerElement={<Link to="/my-second-tab-view" />} value="/my-second-tab-view"> 
        {/* insert your component to be rendered inside the tab here */} 
       </Tab> 
      </Tabs> 
     ); 
    } 
} 

zarządzać „aktywny” nieruchomości na zakładkach, można użyć Właściwość value w komponencie <Tabs> wymaga również posiadania właściwości value dla każdej karty, więc gdy obie właściwości są zgodne, zastosuje ona aktywny styl do tej karty.

+0

gdzie jest 'containerElement' w dokumencie? Jak jest używany? – Henry

0

Jako że @gkatchmar mówi, że można użyć komponentu wyższego rzędu withRouter, ale można również użyć context API. Ponieważ @gkatchmar pokazał już z Routerem, wyświetlę tylko context API. Pamiętaj, że jest to eksperymentalny interfejs API.

https://stackoverflow.com/a/42716055/3850405

import React, {Component} from "react"; 
import {Tabs, Tab} from 'material-ui'; 
import * as PropTypes from "prop-types"; 

export class NavTabs extends Component { 
constructor(props) { 
super(props); 
} 

static contextTypes = { 
    router: PropTypes.object 
} 

handleChange = (event: any , value: any) => { 
    this.context.router.history.push(value); 
}; 

    render() { 
    return (
     <Tabs 
     value={this.context.router.history.location.pathname} 
     onChange={this.handleChange} 
     > 
     <Tab 
      label="Home" 
      value="/" 
     > 
     <div> 
      <Home /> 
     </div> 
     </Tab> 
     <Tab 
      label="Portfolio" 
      value="/portfolio" 
      > 
      <div> 
      <Portfolio /> 
      </div> 
     </Tab> 
     </Tabs>   
    ) 
    } 
} 
1

Oto inne rozwiązanie, korzystając z materiału beta 1.0 i dodając przeglądarkę Wstecz/Dalej do mieszanki:

import React from 'react'; 
import PropTypes from 'prop-types'; 
import { withStyles } from 'material-ui/styles'; 
import AppBar from 'material-ui/AppBar'; 
import Tabs, { Tab } from 'material-ui/Tabs'; 
import { withRouter } from "react-router-dom"; 
import Home from "./Home"; 
import Portfolio from "./Portfolio"; 

function TabContainer(props) { 
    return <div style={{ padding: 20 }}>{props.children}</div>; 
} 

const styles = theme => ({ 
    root: { 
    flexGrow: 1, 
    width: '100%', 
    marginTop: theme.spacing.unit * 3, 
    backgroundColor: theme.palette.background.paper, 
    }, 
}); 

class NavTabs extends React.Component { 
    state = { 
    value: "/", 
    }; 

    componentDidMount() { 
    window.onpopstate =()=> { 
     this.setState({ 
     value: this.props.history.location.pathname 
     }); 
    } 
} 

    handleChange = (event, value) => { 
    this.setState({ value }); 
    this.props.history.push(value); 
    }; 

    render() { 
    const { classes } = this.props; 
    const { value } = this.state; 

    return (
     <div className={classes.root}> 
     <AppBar position="static" color="default"> 
      <Tabs 
      value={value} 
      onChange={this.handleChange} 
      scrollable 
      scrollButtons="on" 
      indicatorColor="primary" 
      textColor="primary" 
      > 
      <Tab label="Home" value = "/" /> 
      <Tab label="Portfolio" value = "/portfolio"/> 
      </Tabs> 
     </AppBar> 
     {value === "/" && <TabContainer>{<Home />}</TabContainer>} 
     {value === "/portfolio" && <TabContainer>{<Portfolio />}</TabContainer>} 
     </div> 
    ); 
    } 
} 

NavTabs.propTypes = { 
    classes: PropTypes.object.isRequired, 
}; 

export default withRouter(withStyles(styles)(NavTabs));