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{
               ...state,
               msg:action.params
          }
       case 'changeNum':
           return{
               ...state,
               num:action.params
          }
       default:
           return state;
  }
}
// 4.定义仓库
const store = createStore(reducer)
export default store;

在任意页面组件中使用仓库中的数据,并通过仓库修改数据

使用仓库中的数据

<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({}))
}

 

posted @ 2021-02-03 17:06  安亦辰00  阅读(72)  评论(0)    收藏  举报