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. ubuntu下面搭建SolrCloud集群
  2. php邮件通知,邮件通知设置
  3. SharePoint 2010 沙盒解决方案以及 Visual Studio 2010 模板
  4. graylog2+syslog-ng+mongodb构建集中管理日志服务器 --转载
  5. 控件包含代码块(即 ),因此无法修改控件集合 (转自http://blog.csdn.net/wangchao1982/archive/2007/11/19/1892472.aspx)...
  6. 10-Qt6 QStringView
  7. 统计消息总数_和公牛一战,库里创三个记录,耀眼的还是三分球总数
  8. Hdu 4415 Assassin's Creed 【贪心】.cpp
  9. 10个适用于Java程序员的有用单元和集成测试工具
  10. python的数值类型_Python的数值类型
  11. 华为鸿蒙新机价格表,华为Mate30已确认:鸿蒙系统+巴龙5000,售价感人
  12. C++使用命名管道使用进程间通信
  13. c语言实验集成环境软件,TurboC for Windows集成实验与学习环境
  14. ubuntu(20.04)+linux内核(5.17.3)的config文件
  15. java 后端处理PDF图册
  16. PHP在线工具箱源码站长引流+在线工具箱源码+多款有趣的在线工具+一键安装
  17. php后台登录页,后台登录页面模板源码
  18. 既然彼此不能相濡以沫, 那就相忘于江湖吧.
  19. css实现图片自动渐变切换、element-plus 的修改el-table的(边框线为虚线、表头样式)
  20. bootstrap X-editable使用。

热门文章

  1. 中国公布北京2022年冬奥会企业赞助有关增值税政策
  2. 【 史上最坑爹的Java代码系列02 】Java中的三种代码块
  3. 华为荣耀/手机平板恢复出厂方法/重置强制解掉屏幕锁开机锁定好位的无法解开的快速有效方案
  4. 最好的jQuery灯箱插件,让您的页面流行
  5. Python读写文件的七种模式(r,w,x,a,b,t,+)
  6. 新品发布全线添员,九号全力奔向“红海”深处?
  7. IT信息技术企业应具备哪些资格
  8. 电子元件知识汇总4-采购
  9. Mysql的MVCC机制
  10. MySQL存储过程系列