14.react路由

1. react路由基本使用

1
2
3
4
5
6
7
8
//react-router的使用步骤:
//1.npm install react-router-dom

//2.引入HashRouter Route Link
//HashRouter 表示使用hash模式的路由
//Route 表示一个路由规则
//Link 表示点击跳转路由
import { HashRouter, Route, Link } from 'react-router-dom'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{/*3.配置路由规则  Route同时会占坑*/}
{/*路由默认会使用模糊匹配
比如:访问路径 /movie 能够匹配 / 和 /movie */}
{/* exact表示精确匹配 :访问路径需要和路由的路径完全一致才能匹配 */} ★
<Route path="/" component={Home} exact></Route>

{/* strict : 如果路由规则中的路径有/,则要求访问路径中也要有/才能匹配(只看/) */}
<Route path="/about/:name/:id" component={About} strict></Route>
<Route path="/movie" component={Movie}></Route>


{/*4.点击Link去访问路由*/}
<Link to="/">来到首页</Link>
<Link to="/about/zhangsan/13">来到关于我们</Link> <Link to="/movie">来到电影</Link>
<br/>
1
2
3
4
5
6
7
8
9
10
11
12
import { withRouter } from 'react-router-dom'

this.props.history.push("/")

export default withRouter (RTab);

<HashRouter>
<RNav></RNav>
<RouterMap></RouterMap>
<Button type='primary'>按钮</Button>
<RTab></RTab>
</HashRouter>

hashrouter 只建议套一个,一般套在最前面

2. switch和redirect和组件懒加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{/*当使用组件懒加载的时候,往往是和Suspense结合使用,fallback表示组件没有加载完毕的时候显示的信息*/}
<Suspense fallback={<div>Loading...</div>}>


{/*Switch表示路由互斥,我们使用Switch之后,只会匹配一个路由规则*/}
<Switch>


{/*我们需要给根路径的路由加上exact属性来精确匹配,否则所有的访问路径都会匹配Home组件*/}
<Route path="/" component={Home} exact></Route>
<Route path="/about/:name/:id" component={About} strict></Route>
<Route path="/movie" component={Movie}></Route>
<Route path="/search" component={Search}></Route>

{/*当没有匹配的路由的时候来到跟路由*/} 重定向
<Redirect to="/" />
</Switch>
</Suspense>

3.路由的传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1.  /*通过params方式传参
获取参数:props.match.params
参数只能是字符串,而且参数会在浏览器地址栏中显示*/
<Link to="/about/zhangsan/13">来到关于我们-params方式传参</Link> <br />
//获取路由中的参数信息
return <div>About组件{props.match.params.id}{props.match.params.name}</div>

2. /*通过search方式传参
获取参数:props.location.search
参数只能是字符串,而且参数会在浏览器地址栏中显示*/
<Link to="/movie?name=xiaoming">来到电影-search方式传参</Link> <br />


3. /*通过query方式传参
获取参数:props.location.query
好处参数可以是对象,参数信息不会在浏览器的地址栏中显示,所以一刷新页面参数就没了*/
<Link to={{ pathname: '/movie', query: { name: 'sunny' } }}>来到电影2-query方式传参</Link> <br />


4. /*通过state方式传参
获取参数:props.location.state
好处参数可以是对象,参数信息不会在浏览器的地址栏中显示,
参数是加密的,所以一刷新页面参数就没了*/
<Link to={{ pathname: '/movie', state: { name: 'haha' } }}>来到电影3-state方式传参</Link> <br />

4.编程式导航

1
2
3
4
5
6
7
8
9
10
11
12
//使用Route包裹的组件会自动将location  history  match注入到组件的props中
//所以在组件中直接可以使用props.location props.history这些信息
// console.log(props)
<Route path="/movie" component={Movie}></Route>
props.history.push({pathname:"/search"})


//如果组件没有使用Route包裹,那么不能使用props的location history match这三个参数
//如果此时我们想要用这三个参数,我们可以将当前组件使用withRouter来包裹

//withRouter可以包装任何自定义组件,将react-router 的 history,location,match 三个对象传入
export default withRouter(MovieDetail);

5.ReactCSSTransitionGroup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//ReactCSSTransitionGroup 使用步骤
//1.通过npm install react-addons-css-transition-group 安装并引入
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');


{/*2.给需要动画的元素包裹ReactCSSTransitionGroup,可以对一组元素进行过渡动画*/}
<ReactCSSTransitionGroup
component="ul"
transitionName="example"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}
transitionAppear={true}
transitionAppearTimeout={500}>
{this.getItems()}
</ReactCSSTransitionGroup>



//3.写动画的样式 (入场动画 出场动画的样式)
import './demo1.css'

/*指定入场动画的开始状态*/
.example-enter {
opacity: 0.01;
}

/*指定入场动画的整个过程*/
.example-enter.example-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}

/*指定出场动画的开始状态*/
.example-leave {
opacity: 1;
}

/*指定出场动画的整个过程*/
.example-leave.example-leave-active {
opacity: 0.01;
transition: opacity 300ms ease-in;
}

/*指定初始动画的样式*/
.example-appear {
opacity: 0.01;
}

/*指定初始动画的整个过程*/
.example-appear.example-appear-active {
opacity: 1;
transition: opacity .5s ease-in;

6. Hook

6.1 hook的基本使用

Hook React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React, { useState } from 'react'
function Demo1(props) {
//count代表state的变量
//setCount是一个function,如果我们要修改count变量,需要通过setCount来修改
let [count, setCount] = useState(0)
let [count2, setCount2] = useState(1)
let [count3, setCount3] = useState(2)

return (<div>
{count}
<button onClick={() => { setCount(++count) }}>点我修改count</button>
<br />
{count2}
<button onClick={() => { setCount2(++count2) }}>点我修改count2</button>
<br />
{count3}
<button onClick={() => { setCount3(++count3) }}>点我修改count3</button>
</div>)
}

export default Demo1;
  • 不要在循环,条件或嵌套函数中调用Hook,确保总是在你的 React 函数的最顶层调用他们。遵守这条规则,你就能确保
    Hook 在每一次渲染中都按照同样的顺序被调用。这让 React 能够在多次的 useStateuseEffect 调用之间保持 hook 状态的正确

6.2 effectHook

Effect Hook 可以让你在函数组件中执行副作用操作

副作用:函数内部的代码不对函数外部的代码产生任何影响

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import React, { useState,useEffect  } from 'react'
import Child from './Child.jsx'

function Demo2(props) {
//count代表state的变量
//setCount是一个function,如果我们要修改count变量,需要通过setCount来修改
let [count, setCount] = useState(0)
let [count2, setCount2] = useState(1)

//useEffect函数可以来模拟class组件的中指定生命周期的钩子函数 componentDidMount,componentDidUpdate,componentWillUnmount

//相当于componentDidMount 、componentDidUpdate
useEffect(()=>{
console.log("xxxxxxxxxxx",count)
})

//相当于componentDidMount
useEffect(()=>{
console.log("yyyyyyyyy")
},[])

//当count2的值被改变之后执行当前的useEffect,其他值改变不会执行这个useEffect
useEffect(()=>{
console.log("zzzzzzzzzzzzz")
},[count2])

//useEffect函数中return的function会在组件重新渲染的时候以及组件卸载的时候执行
useEffect(()=>{
return ()=>{
console.log('hello Hook')
}
})

return (<div>
{count}
<button onClick={() => { setCount(++count) }}>点我修改count</button>
<br />
<button onClick={() => { setCount2(++count2) }}>点我修改count2</button>
<br />
<Child></Child>
</div>)
}

export default Demo2;

6.3 useContext 的使用

作用:可以向子孙组件发布数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//1.在App.jsx
function App(){
return (<MyContext.Provider value={{name:"zhangsan"}}>
App
<Demo2></Demo2>
</MyContext.Provider>)
}



//2.Child.jsx
import React,{useContext} from 'react'
import MyContext from '@/context.js'

export default function(props){
//在子组件中获取父组件发布的数据
const contextValue = useContext(MyContext);
console.log(contextValue)
return (<div>xx</div>)
}


//定义context.js
import React from 'react'
const MyContext = React.createContext();
export default MyContext;