1. 什么是路由
以上是中文维基百科对路由的解释。通俗的来讲,把一个地方的信息传输到他想去的目的地的过程,就叫路由。
2. 用代码解释路由
需求:页面上有2个按钮,分别是登陆和注册,点击登陆按钮,就切换到对应的登陆界面,点击注册按钮,就切换到对应的注册界面。
示例代码:
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">
<div>
<button onClick={()=> setN(0)}>登陆</button>
<button onClick={()=> setN(1)}>注册</button>
</div>
<div>
{ n % 2 === 0 ? <Box1 />:<Box2 />}
</div>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
这个其实就是路由的雏形了,每个页面对应着一个组件,然后在不同状态下去切换 。
3. 新增的需求
提出需求:在分享该页面出去时,用户直接到达注册页面。(以上示例代码的首页是登陆界面)
3.1 修改 url 中的 hash
值
url 中 #(hash) 的含义
URL 的hash
部分,指的是#
后的部分
window.location.hash
可读取或写入hash
值
function Box1() {
return <div className="box">登录</div>;
}
function Box2() {
return <div className="box">注册</div>;
}
function App() {
//获取当前的hash值
let hash = window.location.hash;
let initUI = hash === "#signup" ? "注册" : "登录";
let [ui, setUI] = useState(initUI);
//切换页面时,改hash
let onClickLogin = () => {
setUI("登录");
window.location.hash = "login";
};
let onClickSignUp = () => {
setUI("注册");
window.location.hash = "signup";
};
return (
<div className="App">
<div>
<button onClick={onClickLogin}>登录</button>
<button onClick={onClickSignUp}>注册</button>
</div>
<div>{ui === "登录" ? <Box1 /> : <Box2 />}</div>
</div>
);
}
#signup
: 注册, 空或 #login
: 登录。
不同的界面对应不同的字符串(hash
),把用户送往其想到达的目的地,就是路由。
3.2 除了 hash 还能用什么
但是,地址栏上有这个 “#” 符号不太好看,能不能变好看点?
- 直接修改
pathname
,但会刷新页面
不用
window.location.hash = "login";
而用
window.location.pathname = "/login";
我只是想切换个tab,页面就整个刷新了啊
- 使用
window.history.pushState()
可以不刷新页面而改变pathname
。
window.history.pushState(null, '', '/login')
function App() {
let path = window.location.pathname;
let initUI = path === "/signup" ? "注册" : "登录";
console.log(initUI);
let [ui, setUI] = useState(initUI);
let onClickLogin = () => {
setUI("登录");
window.history.pushState(null, "", "/login");
};
let onClickSignUp = () => {
setUI("注册");
window.history.pushState(null, "", "/signup");
};
return (
<div className="App">
<div>
<button onClick={onClickLogin}>登录</button>
<button onClick={onClickSignUp}>注册</button>
</div>
<div>{ui === "登录" ? <Box1 /> : <Box2 />}</div>
</div>
);
}
3.3 三种方式的区别
-
window.location.hash
(保险办法)
可让url
变化,同时不刷新页面 -
window.location.pathname
会刷新页面,别用 -
window.history.pushState( , , )
(想好看用这个)
不刷新页面,并改变pathname
但 建议:只有后端将所有路径都指向首页时,才使用这个API。
4. React Router
上面的代码存在着重大缺陷:
- 如果
path
过多,代码就要写很多if ... else
- 路由有无限个,无法写
暂不考虑使用正则表达式。使用 React Router 来解决这些问题吧 : )
React Router,保持 UI 和 URL同步。
4.1 安装 React Router
使用命令行:
npm install react-router-dom
注意:
react-router
: 实现了路由的核心功能。
react-router-dom
: 基于react-router,加入了在浏览器运行环境下的一些功能。
写网站的时候一般引入 react-router-dom
就可以了
4.2 使用 React Router
建议查看的官网:react-router
import { BrowserRouter as Router, Switch, Link, Route } from "react-router-dom";
function Home(){
return <div className="box">首页</div>
}
function Login(){
return <div className="box">登录</div>
}
function SignUp(){
return <div className="box">注册</div>
}
function App(){
return(
<div className="app">
<Router>
<div className="nav">
<Link to="/" className="link">首页</Link> | <Link to="/login" className="link">登录</Link> | <Link to="/signup" className="link">注册</Link>
</div>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/login">
<Login />
</Route>
<Route path="/signup">
<SignUp />
</Route>
</Switch>
</Router>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'));