day20
一、路由传参
1.动态路由
(1)定义一个动态路由规则
<Route exact path="/index/user" component={ User }></Route>
{/* 定义一个动态路由规则 */}
<Route path="/index/user/:id" component={ UserInfo }></Route>
Route 路由匹配模式默认是模糊匹配,希望精确匹配时添加exact属性
(2)页面跳转
<button className="btn btn-primary" onClick={ ()=>this.props.history.push('/index/user/' + item.id) }>编辑</button>
(3)获取动态路由参数
在用户详情页面
<p>用户编号:{ this.props.match.params.id }</p>
2.查询参数
(1)定义一个固定的路由规则
<Route path="/index/user/info" component={ UserInfo }></Route>
(2)页面跳转
<button className="btn btn-primary" onClick={ ()=>this.toInfo(item) }>编辑</button>
toInfo(obj){
this.props.history.push('/index/user/info?'+qs.stringify(obj))
}
(3)在信息页面获取路由参数
this.props.location.search
componentDidMount(){
//qs.parse 是把参数名=参数值&参数名N=参数值N字符串格式转换成对象
var obj = qs.parse(this.props.location.search.substr(1));
this.setState({
info:obj
})
}
二、高阶组件-withRouter
通过路由规则直接渲染出来的页面组件,在this.props就包含当前的路由信息
但是如果是页面组件部分组件,它不是通过路由规则直接渲染出来的,这个组件的this.props中就不包含当前的路由规则信息
react-router-dom中withRouter高阶组件就可以让非路由规则直接渲染出来的组件包含路由信息
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
class Del extends Component {
del(){
console.log(this)
}
render() {
return (
<div>
<button className="btn btn-danger" onClick={ ()=>this.del() }>删除</button>
</div>
)
}
}
export default withRouter(Del);
三、状态管理
1.flux
(1)介绍
Flux 是一个Facebook开发的、利用单向数据流实现的应用架构,用于 React。
Flux应用有三个主要的部分组成:调度程序、存储和视图(React 组件)。
流程:
-
view 触发 action
-
action 通知 dispatcher(调度程序)
-
dispatcher通知store(仓库)修改数据
-
store仓库修改完数据后,通知页面进行重新渲染。
图示:
(2)安装
npm i flux --save
(3)基本使用
①初始化仓库
在src目录下创建一个store目录,在store目录下创建一个index.js,并初始化仓库
let state = {
name : 'study flux'
}
export default { state }
②在任意页面组件中引入仓库并使用仓库中的数据
import React, { Component } from 'react'
import store from '../../store'
export default class Index extends Component {
render() {
return (
<div>
<h1>首页</h1>
<h2>仓库中的name:{ store.state.name }</h2>
</div>
)
}
}
③引入Dispatcher调度程序,并注册具体的调度任务
/src/store/index.js
//引入调度程序
import { Dispatcher } from 'flux'
//设置初始数据
let state = {
name : 'study flux'
}
//设置调度程序,实现数据可预测变化
let dispatcher = new Dispatcher();
dispatcher.register(action=>{
switch(action.type){
case 'changeName':
state.name = action.params;
break;
default:
break;
}
})
export default { state,dispatcher }
④在任意页面组件触发调度程序,实现数据的变化
<button onClick={ ()=>store.dispatcher.dispatch({type:'changeName',params:'index name'}) }>改变name</button>
此时,仓库中的数据已经发生了变化,但是,页面没有重新渲染
⑤在仓库中引入事件监听器,在仓库数据更新完成后,触发一个事件,用来告知页面组件重新渲染
/src/store/index.js
import EventEmitter from 'events'
//引入调度程序
import { Dispatcher } from 'flux'
//设置初始数据
// let state = {
// name : 'study flux'
// }
class State extends EventEmitter{
name = 'study flux'
}
let state = new State();
//设置调度程序,实现数据可预测变化
let dispatcher = new Dispatcher();
dispatcher.register(action=>{
switch(action.type){
case 'changeName':
state.name = action.params;
break;
default:
break;
}
//数据在仓库中修改完成后,通知页面
state.emit('update')
})
export default { state,dispatcher }
⑥在页面组件中的挂载完成钩子函数中,监听事件,实现页面重新渲染
componentDidMount(){
store.state.on('update',()=>{
this.setState({})//调用setState,来实现页面重新渲染
})
}
2.redux
(1)介绍
Redux 是针对 JavaScript 应用程序的可预测状态容器。
Redux由Dan Abramov在2015年创建的科技术语。是受2014年Facebook的Flux架构以及函数式编程语言Elm启发。很快,Redux因其简单易学体积小在短时间内成为最热门的前端架构。
核心概念:
-
actions
-
store
-
reducers
redux三个原则:
-
单一数据源
-
state是只读的
-
使用纯函数来修改state
(2)安装
npm i redux --save
(3)基本流程
-
引入createStore
-
定义初始状态
-
定义纯函数
-
定义仓库
示例代码:
封装仓库,定义初始数据和修改数据的方法
/src/store/index.js
// 1.引入createStore
import { createStore } from 'redux'
// 2.定义初始状态
const initalState = {
msg : 'redux demo',
num : 100
}
// 3.定义纯函数
function reducer(state = initalState,action){
switch(action.type){
case 'changeMsg':
//数据处理逻辑
return{
在任意页面组件中使用仓库中的数据,并通过仓库修改数据
使用仓库中的数据
<h2>仓库中msg:{ store.getState().msg }</h2>
<h2>仓库中num:{ store.getState().num }</h2>
调用仓库中的方法来修改数据
<button onClick={ ()=>this.setMsg() }>改变msg</button>
setMsg(){
store.dispatch({
type:'changeMsg',
params:'等来的是命运'
})
}
componentDidMount(){
//使用仓库中的订阅者来监测数据的变化,仓库数据变化后,页面重新渲染
store.subscribe(()=>this.setState({}))
}

浙公网安备 33010602011771号