react 路由導航欄 withRouter

codesandbox https://codesandbox.io/s/9l6prnyxjyreact

app.js

import React, { Component, Fragment } from "react";
import {
  AppBar,
  Button,
  Tabs,
  Tab,
  Icon,
  Typography,
  Fade,
  Slide
} from "@material-ui/core";
import _ from "lodash";
import {
  BrowserRouter,
  HashRouter,
  Link,
  Redirect,
  Route,
  Switch,
  withRouter
} from "react-router-dom";

const l = console.log;

let Home = props => {
  return (
    <Fragment>
      <Typography variant="headline">首頁</Typography>
    </Fragment>
  );
};
let About = props => {
  return (
    <Fragment>
      <Typography variant="headline">關於</Typography>
    </Fragment>
  );
};

let Mine = props => {
  return (
    <Fragment>
      <Typography variant="headline">個人</Typography>
    </Fragment>
  );
};

@withRouter
class Tabbars extends Component {
  state = {
    tabs: [
      {
        label: "home",
        to: "/home",
        icon: "home"
      },
      {
        label: "about",
        icon: "supervised_user_circle",
        to: "/about"
      },
      {
        label: "mine",
        icon: "perm_identity",
        to: "/mine"
      }
    ],
    value: 0
  };
  handleChange = (event, value) => {
    this.setState({ value });
  };
  toNav = to => e => {
    this.props.history.push(to);
  };

  componentWillMount() {
    // l(this.props)
    let { location, history } = this.props;

    // 確保用戶在瀏覽器改變路由,激活按鈕發生變化
    this.changeTabbarValue(location.pathname);

    // 監聽路由的變化,主要用於重定向時確保激活按鈕發生變化
    history.listen(({ pathname }, action) => {
      l("router change");
      // action === "REPLACE" &&
      this.changeTabbarValue(pathname);
    });
  }

  changeTabbarValue(pathname) {
    let i = this.state.tabs.findIndex(({ to }) => to.includes(pathname));
    if (i < 0) {
      return l("沒找到根路由");
    }
    i !== this.state.value &&
      this.setState({
        value: i
      });
  }

  componentDidMount() {
    document.title = "Ajanuw";
  }

  render() {
    return (
      <AppBar position="static" color="default">
        <Tabs
          value={this.state.value}
          onChange={this.handleChange}
          indicatorColor="primary"
          textColor="primary"
          fullWidth
        >
          {this.state.tabs.map(($_, index) => {
            return (
              <Tab
                label={$_.label}
                key={index}
                onClick={this.toNav($_.to)}
                icon={<Icon>{$_.icon}</Icon>}
              />
            );
          })}
        </Tabs>
      </AppBar>
    );
  }
}

//  Tabbars = withRouter(Tabbars)

class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <Fragment>
          <Tabbars />
          {/* 路由中有重定向, 加入動畫效果可能會報錯 */}
          <Switch>
            {/* <Route
                exact
                strict
                path="/"
                render={props => true && (<Redirect to='/home'/>)}
              /> */}
            {/* <Redirect exact from='/' to='/home'/> */}
            <Redirect from="/" to="/home" exact strict />
            <Route
              exact
              strict
              path="/home"
              render={props => <Home {...props} />}
            />
            <Route path="/about" component={About} />
            <Route path="/mine" component={Mine} />
            <Route
              render={() => {
                return <div>404</div>;
              }}
            />
          </Switch>
        </Fragment>
      </BrowserRouter>
    );
  }
}

export default App;

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import CssBaseline from "@material-ui/core/CssBaseline";
import { createMuiTheme, MuiThemeProvider } from "@material-ui/core/styles";
import { pink, blue } from "@material-ui/core/colors";

// 自定義主題
const theme = createMuiTheme({
  palette: {
    primary: blue,
    secondary: pink
  }
});

ReactDOM.render(
  <React.Fragment>
    <CssBaseline />
    <MuiThemeProvider theme={theme}>
      <App />
    </MuiThemeProvider>
  </React.Fragment>,
  document.getElementById("root")
);
相關文章
相關標籤/搜索