美文网首页
react router

react router

作者: sweetBoy_9126 | 来源:发表于2019-09-29 11:38 被阅读0次

一个简单的路由小demo

  1. 我们页面显示一个登录注册按钮,点击登录,内容跟着显示登录,点击注册内容里显示注册
function Box1() {
  return <div className="box">登录</div>;
}
function Box2() {
  return <div className="box">注册</div>;
}
function App() {
  let [n, setN] = useState(0);
  return (
    <div className="App">
      <button onClick={() => setN(1)}>登录</button>
      <button onClick={() => setN(0)}>注册</button>
      <div>{n % 2 === 0 ? <Box1 /> : <Box2 />}</div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
  1. 使用hash做为路由
    我们现在想要实现页面链接分享给别人的时候,每次默认显示注册,但我们上面的代码每次页面一打开都是显示的登录,所以我们需要通过hash来对应不同的路由
function Box1() {
  return <div className="box">登录</div>;
}
function Box2() {
  return <div className="box">注册</div>;
}
function App() {
  let hash = window.location.hash;
  let initUi = hash === "#login" ? "登录" : "注册";
  let [n, setN] = useState(initUi);
  let setLogin = () => {
    setN("登录");
    window.location.hash = "#login";
  };
  let setSign = () => {
    setN("注册");
    window.location.hash = "#sign";
  };
  return (
    <div className="App">
      <button onClick={setLogin}>登录</button>
      <button onClick={setSign}>注册</button>
      <div>{n === "登录" ? <Box1 /> : <Box2 />}</div>
    </div>
  );
}
  1. 使用history也可以实现改变路由页面不刷新
function App() {
  let hash = window.location.pathname;
  console.log(hash);
  let initUi = hash === "/sign" ? "注册" : "登录";
  let [n, setN] = useState(initUi);
  let setLogin = () => {
    setN("登录");
    window.history.pushState({}, "", "login");
  };
  let setSign = () => {
    setN("注册");
    window.history.pushState({}, "", "sign");
  };
  return (
    <div className="App">
      <button onClick={setLogin}>登录</button>
      <button onClick={setSign}>注册</button>
      <div>{n === "登录" ? <Box1 /> : <Box2 />}</div>
    </div>
  );
}

如果想要页面不刷新实现路由跳转的方法:

  1. hash默认
  2. history模式
    缺点:需要后端支持,把所有的路径都默认指向首页

如果路由变多,我们该怎么办

在上面代码的基础上添加一个欢迎

function Box1() {
  return <div className="box">登录</div>;
}
function Box2() {
  return <div className="box">注册</div>;
}
function Box3() {
  return <div className="box">欢迎</div>;
}
function App() {
  let path = window.location.pathname;
  let initUi = "";
  if (path === "/welcome") {
    initUi = "欢迎";
  } else if (path === "/sign") {
    initUi = "注册";
  } else {
    initUi = "登录";
  }
  let [n, setN] = useState(initUi);
  let setLogin = () => {
    setN("登录");
    window.history.pushState({}, "", "login");
  };
  let setSign = () => {
    setN("注册");
    window.history.pushState({}, "", "sign");
  };
  let setWelcom = () => {
    setN("欢迎");
    window.history.pushState({}, "", "welcome");
  };
  let showN = () => {
    if (n === "登录") {
      return <Box1 />;
    } else if (n === "欢迎") {
      return <Box3 />;
    } else {
      return <Box2 />;
    }
  };
  return (
    <div className="App">
      <button onClick={setWelcom}>欢迎</button>
      <button onClick={setLogin}>登录</button>
      <button onClick={setSign}>注册</button>
      <div>{showN()}</div>
    </div>
  );
}

完整代码:
https://codesandbox.io/s/modern-wildflower-k0965

上面代码的问题:
1). 如果路由过多,我们的path里的if和else就会写的很长
2). 如果它的路由是无限多个,我们根本没法写,因为我们不知道它有哪些

使用ReactRouter解决路由过多和路由个数无法确定的问题

  1. 安装react-router-demo
yarn add react-router-demo
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

import "./styles.css";

function App() {
  return <div>App</div>;
}
function Welcome() {
  return <div>欢迎</div>;
}
function Box2() {
  return <div>登录</div>;
}
const rootElement = document.getElementById("root");
ReactDOM.render(
  <Router>
    <div>
      <div>
        <Link to="/">首页</Link>
        <Link to="/login">登录</Link>
        <Link to="/welcom">欢迎</Link>
      </div>
      <Route path="/" exact component={App} />
      <Route path="/login" component={Box2} />
      <Route path="/welcom" component={Welcome} />
    </div>
  </Router>,
  rootElement
);

完整代码:
https://codesandbox.io/s/festive-wright-g775f

路由传参方式
  1. params
<Route path={"/detail/:id"} component={Detail} exact></Route>
<Link to={`/detail/${item.get('id')}`} key={index}>

可选参数

<Route path={"/detail/:id/:keyword?"} component={Detail} exact></Route>

上面的keyword就是可选参数,也就是在参数后加问号
获取参数通过props.match.params.id

  1. query
<Link to={`/detail?id=${item.get('id')}`} key={index}>
<Route path={"/detail"} component={Detail} exact></Route>

获取参数通过props.location.search可以获取到?id=1,需要截取

Switch
<Switch>
  <Route path="/" component={Main}></Route>
  <Route path="/about" component={About}></Route>
  <Route path="/topics" component={Topic}></Route>
</Switch>

Switch只允许匹配一个,一旦发现到匹配的路由后就不会再往下走了,比如上面的当匹配到/后发现第一个就匹配所以不会再继续往下走了

嵌套组件
import Main from './Main.tsx'
<Route path="/main" render={() =>
  <Main>
    <Route path="/main/a" component={About}></Route>
  </Main>
}></Route>
-Main.tsx
render() {
  <div>
    this is main page
    <Link to="/main/a"></Link>
    {this.props.children}
  </div>
}
未匹配到的路由配置(404页面)
import * as React from 'react'
import {HashRouter as Router, Route, Link, Switch} from 'react-router-dom';
import Home from './Home'
import Main from '../route1/Main';
import About from '../route1/About';
import Topic from '../route1/Topic';
import NoMatch from './NoMatch'
export default class IRouter extends React.Component {
  render() {
    return (
      <Router>
        <Home>
          <Switch>
            <Route path={"/main"} render={() =>
              <Main>
                <Route path={"/main/:value"} component={About}></Route>
              </Main>
            }></Route>
            <Route path={"/about"} component={About}></Route>
            <Route path={"/topics"} component={Topic}></Route>
            <Route component={NoMatch}></Route>
          </Switch>
        </Home>
      </Router>
    )
  }
}
  • NoMatch.tsx
import * as React from 'react'
export default class NoMatch extends React.Component {
  render() {
    return (
      <div>
        404
      </div>
    )
  }
}

相关文章

网友评论

      本文标题:react router

      本文链接:https://www.haomeiwen.com/subject/dxbouctx.html