一个简单的路由小demo
- 我们页面显示一个登录注册按钮,点击登录,内容跟着显示登录,点击注册内容里显示注册
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);
- 使用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>
);
}
- 使用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>
);
}
如果想要页面不刷新实现路由跳转的方法:
- hash默认
- 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解决路由过多和路由个数无法确定的问题
- 安装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
路由传参方式
- 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
- 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>
)
}
}
网友评论