React-router
React-router安装
方式1:
npx create-react-app demo-app
cd demo-app
npm install react-router-dom
npm start
方式2:<script src="https://unpkg.com/react-router/umd/react-router.min.js"></script>
安装create-react-app并创建一个新项目。
基础路由
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
export default function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
{/* <Switch>通过其子<Route> s查找呈现与当前URL匹配的第一个 */}
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Users() {
return <h2>Users</h2>;
}
嵌套路由
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch,
useParams
} from "react-router-dom";
export default function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/topics">
<Topics />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Topics() {
let match = useRouteMatch();
return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/components`}>Components</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
{/* 主题页面有自己的<Switch>,其中包含更多路线建立在/ topics URL路径上的文件。 你可以想到第二个<Route>作为所有主题的“索引”页面,或者没有选择主题时显示的页面 */}
<Switch>
<Route path={`${match.path}/:topicId`}>
<Topic />
</Route>
<Route path={match.path}>
<h3>Please select a topic.</h3>
</Route>
</Switch>
</div>
);
}
function Topic() {
let { topicId } = useParams();
return <h3>Requested topic ID: {topicId}</h3>;
}
React Router中的组件主要分为三类:
路由器,像<BrowserRouter>
和<HashRouter>
路线匹配器,例如<Route>
和<Switch>
导航,像<Link>
,<NavLink>
和<Redirect>
TodoList脚手架实例
npx create-react-app demo-app
cd demo-app
公共npm注册表中安装React Router:
npm install react-router-dom
安装node-sass
npm install node-sass
ant组件库地址:
http://ant.design/
导入:npm install antd --save
(如果网络环境不佳,推荐使用 cnpm)
2.yarn安装:
$ yarn create react-app antd-demo
或 $ npx create-react-app antd-demo
进入项目并启动
$ cd antd-demo
$ yarn start
从 yarn 或 npm 安装并引入 antd。
$ yarn add antd
程序入口:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
组件 APP.js
import React from 'react';
import './App.scss';
// function App() {
// return (
// <div className="App">
// <h1>欢迎学习react</h1>
// <h1>Hello,World</h1>
// <input type="text" onChange={}/>
// </div>
// );
// }
class App extends React.Component{
state = {
val: '',
list: []
}
handleChange = (event)=>{
let val = event.target.value;
this.setState({
val
})
}
handleAdd = ()=>{
let {val,list} = this.state;
list.push(val);
this.setState({
list
})
}
render(){
const {val,list} = this.state;
const ListItem = list.map((item,index)=>{
return <li key="index">{item}</li>
});
return <div>
<h1>欢迎学习react</h1>
<h1>Hello,World</h1>
<input type="text" value={val} onChange={this.handleChange} />
<button onClick={this.handleAdd}>添加</button>
<ul>
{ListItem}
</ul>
</div>
}
}
export default App;
App.sass
div {
text-align: center;
font-size: 32px;
h1{
color: red;
font-size: 30px;
}
}
路由基本配置
1.BrowserRouter/HashRouter
1.用BrowserRouter
入口文件index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Router from './router';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<React.StrictMode>
<Router />
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
Router.js
import React from 'react';
import {BrowserRouter as Router, Route} from 'react-router-dom'
import App from './pages/app'
import Login from './pages/login'
import Home from './pages/home'
export default function IRouter(){
return <Router>
<Route path="/" component={App}></Route>
<Route path="/login" component={Login}></Route>
<Route path="/home" component={Home}></Route>
</Router>
}
三个子页面
app.js
import React from 'react'
export default function App(){
return <div>This is App</div>
}
login.js
import React from 'react'
export default function Login(){
return <div>This is Login</div>
}
home.js
import React from 'react'
export default function Home(){
return <div>This is Home</div>
}
通过http://localhost:3000/home访问时,会出现
This is App
This is Home
(只要匹配都显示)
2.用HashRouter
import {HashRouter as Router, Route, Switch} from 'react-router-dom'
访问路径变为 http://localhost:3000/#/login,其他一样
2.Switch
添加Switch
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom'
<Switch>
<Route path="/" component={App}></Route>
<Route path="/login" component={Login}></Route>
<Route path="/home" component={Home}></Route>
</Switch>
会出现
This is App
(只显示优先被匹配上的页面)
3.Route-exact/path/component
准确匹配,在短路径上加上exact,就能正常显示
router.js
<Route exact path="/" component={App}></Route>
4.Link/NavLink
app.js
链接跳转
import React from 'react'
import { Link } from 'react-router-dom'
import './app.scss'
import 'antd/dist/antd.css'
export default function App(){
return <div className="container">
<h1>欢迎学习react</h1>
<Link to="/login">点击跳转到登录页面</Link><br/>
<Link to="/home">点击跳转到主页面</Link><br/>
</div>
}
2.有状态组件,class实现
点击按钮跳转
import React from 'react'
import { Link } from 'react-router-dom'
import {Button} from 'antd'
import './app.scss'
import 'antd/dist/antd.css'
// class实现,有状态组件
export default class App extends React.Component{
handleJump = ()=>{
this.props.history.push('/login');
}
render(){
return <div className="container">
<h1>欢迎学习react</h1>
<Link to="/login">点击跳转到登录页面</Link><br/>
<Link to="/home">点击跳转到主页面</Link><br/>
<Button onClick={this.handleJump}>登录跳转</Button>
</div>
}
}
路由动态配置
1.路径带变量:http://localhost:3000/detail/90
2.页面重定向
import {BrowserRouter as Router, Route, Switch, Redirect} from 'react-router-dom'
<Route path="/home" component={Home}>
<Redirect to="/login"></Redirect>
</Route>
<Route path="/detail/:id" component={Detail}></Route>
detail.js
import React from 'react'
import './app.scss'
import 'antd/dist/antd.css'
export default function Detail(){
return <div className="container">
this thi detail.
</div>
}
3.路径不匹配时
import React from 'react'
export default function NoMatch(){
return <div style={{color: 'red'}}>404!!!!</div>
}
import Nomatch from './pages/404'
<Route path="*" component={Nomatch}></Route>
React Hook应用(解决函数无状态问题)
useState
class改变状态要设置初始state状态并另写函数,用useState直接设值
import React,{useState} from 'react'
import { Link } from 'react-router-dom'
import {Button} from 'antd'
import './app.scss'
import 'antd/dist/antd.css'
export default function App(){
const [count,setCount] = useState(10)
return <div className="container">
<h1>欢迎学习react</h1>
<Link to="/login">点击跳转到登录页面</Link><br/>
<Link to="/home">点击跳转到主页面</Link><br/>
<p>
当前count:{count}
</p>
<Button onClick={()=>{setCount(count+1)}}>更新次数</Button>
</div>
}
useEffect
导入useEffect
import React,{useState,useEffect} from 'react'
1.初始渲染时和点击按钮时,都会执行
useEffect(()=>{
console.log('执行了useEffect')
// 改变初始state状态
setCount(100)
})
2.只在初始渲染时,执行
useEffect(()=>{
console.log('执行了useEffect')
setCount(100)
},[])
路由 Hook应用(解决路径跳转和传参问题)
如何获取路径上的参数值:http://localhost:3000/detail/45
1.class
通过this.props.match.params.id
获取,和<Route path="/detail/:id" component={Detail}></Route>
配合使用
import React from 'react'
import './app.scss'
import 'antd/dist/antd.css'
export default class Detail extends React.Component{
render(){
return <div className="container">
<h1>欢迎学习react</h1>
<p>当前参数的ID值为:{this.props.match.params.id}</p>
</div>
}
}
useParams
用useParams().id获取参数
import React from 'react'
import { useParams } from 'react-router-dom'
import './app.scss'
import 'antd/dist/antd.css'
export default function Detail(){
const params = useParams();
return <div className="container">
this thi detail.
{/* {"id":"45"} */}
{JSON.stringify(params)}
{/* 45 */}
{params.id}
</div>
}
useHistory
用 useHistory().push(’/’)跳转页面
import React from 'react'
import { useParams, useHistory } from 'react-router-dom'
import { Button } from 'antd'
import './app.scss'
import 'antd/dist/antd.css'
export default function Detail(){
const params = useParams();
const history = useHistory();
return <div className="container">
<p>this thi detail.</p>
<p>当前参数为:{params.id}</p>
<p>转成josn:{JSON.stringify(params)}</p>
<Button onClick={()=>{
history.push('/')
}}>跳转首页</Button>
</div>
}