1.我使用withRouter使解决什么问题?

我在项目中使用了antd的Menu组件,其中defaultOpenKeys和defaultSelectedKeys两个属性要是设为一个固定的值,每次刷新页面的时候路由不变,但导航的高亮项就会重回最初的状态,这跟实际需求不符,我需要高亮项跟路由是对应的。所以我需要把defaultOpenKeys和defaultSelectedKeys两个属性设置为一个变化的值,此时若跟路由的变化对应上就再好不过了,但是由于在这组件中还获取不到this.props.location,所以需要使用withRouter给它包装一下。

const SystemSider = withRouter(class extends React.Component<RouteComponentProps> {render(){console.log(this.props, this.props.location.pathname.split('/')[1],this.props.location.pathname.split('/')[2])return (<Sider width={200} style={{ background: '#fff' }}><Menu mode="inline" defaultOpenKeys={[this.props.location.pathname.split('/')[1]]} defaultSelectedKeys={[this.props.location.pathname.split('/')[2]]} style={{ height: '100%', borderRight: 0 }}><SubMenu key="official" title={ <span> <Icon type="user" /> 公文管理 </span> }><Menu.Item key='main'><Link to='/official/main'>收文登记</Link></Menu.Item><Menu.Item key='file'><Link to='/official/file'>档案借阅</Link></Menu.Item><Menu.Item key='borrowManage'><Link to='/official/borrowManage'>借阅管理</Link></Menu.Item><Menu.Item key="4">规章制度</Menu.Item><Menu.Item key="5">质量管理</Menu.Item><Menu.Item key="6">合同模版</Menu.Item></SubMenu><SubMenu key="sub2" title={ <span> <Icon type="laptop" /> 审批流程</span>}><Menu.Item key="7">我的申请</Menu.Item><Menu.Item key="8">我的待办</Menu.Item></SubMenu></Menu></Sider>)}
});

2.怎么使用withRouter?

withRouter是react-router-dom中的一个高阶组件 ,要先引入才能使用

import { BrowserRouter as Router, Route, Link, Switch, withRouter, RouteComponentProps } from 'react-router-dom'

由于withRouter是一个高阶组件,使用高阶组件时有两种方法:1⃣️函数式调用 2⃣️装饰器

若使用装饰器的话,在ts中,编译器会对装饰器作用的值做签名一致性检查,而我们在高阶组件中一般都会返回新的组件,并且对被作用的组件的props进行修改(添加、删除)等。这些会导致签名一致性校验失败,ts会给出错误提示。若想使用装饰器,要在@withRouter上面加上//@ts-ignore忽略ts校验

3. 如何正确声明高阶组件呢?

装饰器:将高阶组件注入的属性都声明可选(通过Partial这个映射类型),或者将其声明到额外的injected组件实例属性上。

// @ts-ignore
@withRouter
class SystemSider extends React.Component<{}> {get injected() {return this.props as RouteComponentProps}render(){return (<Sider width={200} style={{ background: '#fff' }}><Menu mode="inline" defaultOpenKeys={[this.injected.location.pathname.split('/')[1]]} defaultSelectedKeys={[this.injected.location.pathname.split('/')[2]]} style={{ height: '100%', borderRight: 0 }}><SubMenu key="official" title={ <span> <Icon type="user" /> 公文管理 </span> }><Menu.Item key='main'><Link to='/official/main'>收文登记</Link></Menu.Item><Menu.Item key='file'><Link to='/official/file'>档案借阅</Link></Menu.Item><Menu.Item key='borrowManage'><Link to='/official/borrowManage'>借阅管理</Link></Menu.Item><Menu.Item key="4">规章制度</Menu.Item><Menu.Item key="5">质量管理</Menu.Item><Menu.Item key="6">合同模版</Menu.Item></SubMenu><SubMenu key="sub2" title={ <span> <Icon type="laptop" /> 审批流程</span>}><Menu.Item key="7">我的申请</Menu.Item><Menu.Item key="8">我的待办</Menu.Item></SubMenu></Menu></Sider>)}
};
export default SystemSider
// @ts-ignore
@withRouter
class SystemSider extends React.Component<Partial<RouteComponentProps>> {render(){console.log(this.props)return (<Sider width={200} style={{ background: '#fff' }}>{/** 这里要使用非空类型断言*/}<Menu mode="inline" defaultOpenKeys={[this.props.location!.pathname.split('/')[1]]} defaultSelectedKeys={[this.props.location!.pathname.split('/')[2]]} style={{ height: '100%', borderRight: 0 }}><SubMenu key="official" title={ <span> <Icon type="user" /> 公文管理 </span> }><Menu.Item key='main'><Link to='/official/main'>收文登记</Link></Menu.Item><Menu.Item key='file'><Link to='/official/file'>档案借阅</Link></Menu.Item><Menu.Item key='borrowManage'><Link to='/official/borrowManage'>借阅管理</Link></Menu.Item><Menu.Item key="4">规章制度</Menu.Item><Menu.Item key="5">质量管理</Menu.Item><Menu.Item key="6">合同模版</Menu.Item></SubMenu><SubMenu key="sub2" title={ <span> <Icon type="laptop" /> 审批流程</span>}><Menu.Item key="7">我的申请</Menu.Item><Menu.Item key="8">我的待办</Menu.Item></SubMenu></Menu></Sider>)}
};
export default SystemSider

函数式调用:(除了开头那种方法之外还可写成如下所示:)

class SystemSider extends React.Component<{}> {get injected() {return this.props as RouteComponentProps}render(){console.log(this.props)return (<Sider width={200} style={{ background: '#fff' }}><Menu mode="inline" defaultOpenKeys={[this.injected.location.pathname.split('/')[1]]} defaultSelectedKeys={[this.injected.location.pathname.split('/')[2]]} style={{ height: '100%', borderRight: 0 }}><SubMenu key="official" title={ <span> <Icon type="user" /> 公文管理 </span> }><Menu.Item key='main'><Link to='/official/main'>收文登记</Link></Menu.Item><Menu.Item key='file'><Link to='/official/file'>档案借阅</Link></Menu.Item><Menu.Item key='borrowManage'><Link to='/official/borrowManage'>借阅管理</Link></Menu.Item><Menu.Item key="4">规章制度</Menu.Item><Menu.Item key="5">质量管理</Menu.Item><Menu.Item key="6">合同模版</Menu.Item></SubMenu><SubMenu key="sub2" title={ <span> <Icon type="laptop" /> 审批流程</span>}><Menu.Item key="7">我的申请</Menu.Item><Menu.Item key="8">我的待办</Menu.Item></SubMenu></Menu></Sider>)}
};
// @ts-ignore
export default withRouter(SystemSider)

参考文档:https://blog.csdn.net/sinat_17775997/article/details/84203095

react+ts项目实战:如何使用withRouter?相关推荐

  1. Vue ts 项目实战

    Vue ts 项目实战 首先,没装vue-cli的,可以使用下列任一命令安装这个新的包: npm install -g @vue/cli # OR yarn global add @vue/cli 安 ...

  2. 【腾讯Bugly干货分享】React Native项目实战总结

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 "8小时内拼工作,8小 ...

  3. 创建React + Ts项目

    一.安装react+ts npx create-react-app my-app --template typescript 二.安装eslint代码检测 yarn eslint npx eslint ...

  4. React + Ts项目搭建

    一.安装react+ts npx create-react-app my-app --template typescript 二.安装eslint代码检测 一个好的项目必须有一个规范,所以得安装esl ...

  5. React + TS项目开发小技巧总结

    一.react hook知识 1.基本使用 最常用的Hook,有两个:useState.useEffect import React, { useState } from "react&qu ...

  6. React Native项目实战之搭建美团个人中心界面

    在很多app应用型APP中,个人中心往往会单独出一个模块,而对于刚入门React Native的朋友来说,怎么去实现一些静态的页面,并且怎么着手实现,怎么分层,怎么去实现这个架构,我想是很基础的(ps ...

  7. TS核心知识点总结及项目实战案例分析

    前言 最近工作一直很忙,复盘周期也有所拉长,不过还是会坚持每周复盘.今天笔者将复盘一下typescript在前端项目中的应用,至于为什么要学习typescript,我想大家也不言自明,目前主流框架vu ...

  8. 搭建react项目,react+ts,react+typescript

    1.使用create-react-app my-react 目前使用create-react-app会遇到以下错误提示: 该错提示我们 您正在运行 create-react-app 5.0.0,它落后 ...

  9. 基于 mapboxgl+threejs+react+ts 三维 webgis 实战系列教程

    全网唯一 基于 mapboxgl+threejs+react+ts 的 三维 webgis 实战系列教程: 后续将分享一些下面的功能: 基本项目搭建: threejs + mapboxgl 版 Hel ...

最新文章

  1. SQLServer 系统表
  2. 【PHP源码分析】small内存规格的计算
  3. 虚拟机下Linux安装图解之二:虚拟机的创建
  4. eclipse创建Maven的动态web工程
  5. ROS 命令以及相关内容学习(二)
  6. mysql数据库显示问号_mysql数据库中文显示问号
  7. 对象调用方法方法及其call调用
  8. 多变量微积分笔记19——直角坐标系和柱坐标系下的三重积分
  9. OneNote 使用汇总
  10. C# 用itextsharp把Html转PDF
  11. 怎样将UltraISO做的启动U盘还原成原来的样子
  12. 新手自己搭建、开发网络直播平台历程——了解实现一个简单直播平台的结构
  13. Centos8使用yum报错 Couldn‘t resolve host name for http://mirrorlist.centos.org/?releas
  14. GMAP.NET应用及离线地图加载
  15. C语言程序代码 25 编程实现将任意一个华氏法表示的温度,转换为以摄氏法表示的温度。
  16. 【数据挖掘】知识总结——背景、定义、一般流程及应用(一)
  17. 长江存储一笔高额投资,让SK海力士开始钻研我国专利法
  18. IPv6设备配置选项
  19. html5在哪编辑器,HTML5文本编辑器推荐-属于Web开发人员的HTML5编辑器
  20. linux中giep命令作用,Linux查看硬件信息以及驱动设备的命令

热门文章

  1. 绘制八角星形 python_Python绘图库及二级训练集
  2. 中科院+华为,我们能得到什么?
  3. 计算100以内的质数和
  4. openssl_encrypt 加密解密
  5. 实现应用软件能够通过运行窗口打开
  6. Java Map 深拷贝方法
  7. java计算机毕业设计理发预约系统源代码+数据库+系统+lw文档
  8. java自带的md5加密_JDK自带MD5加密算法
  9. Linux useradd userdel命令
  10. 《软件方法》强化自测题-分析(1)