react+ts项目实战:如何使用withRouter?
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?相关推荐
- Vue ts 项目实战
Vue ts 项目实战 首先,没装vue-cli的,可以使用下列任一命令安装这个新的包: npm install -g @vue/cli # OR yarn global add @vue/cli 安 ...
- 【腾讯Bugly干货分享】React Native项目实战总结
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 "8小时内拼工作,8小 ...
- 创建React + Ts项目
一.安装react+ts npx create-react-app my-app --template typescript 二.安装eslint代码检测 yarn eslint npx eslint ...
- React + Ts项目搭建
一.安装react+ts npx create-react-app my-app --template typescript 二.安装eslint代码检测 一个好的项目必须有一个规范,所以得安装esl ...
- React + TS项目开发小技巧总结
一.react hook知识 1.基本使用 最常用的Hook,有两个:useState.useEffect import React, { useState } from "react&qu ...
- React Native项目实战之搭建美团个人中心界面
在很多app应用型APP中,个人中心往往会单独出一个模块,而对于刚入门React Native的朋友来说,怎么去实现一些静态的页面,并且怎么着手实现,怎么分层,怎么去实现这个架构,我想是很基础的(ps ...
- TS核心知识点总结及项目实战案例分析
前言 最近工作一直很忙,复盘周期也有所拉长,不过还是会坚持每周复盘.今天笔者将复盘一下typescript在前端项目中的应用,至于为什么要学习typescript,我想大家也不言自明,目前主流框架vu ...
- 搭建react项目,react+ts,react+typescript
1.使用create-react-app my-react 目前使用create-react-app会遇到以下错误提示: 该错提示我们 您正在运行 create-react-app 5.0.0,它落后 ...
- 基于 mapboxgl+threejs+react+ts 三维 webgis 实战系列教程
全网唯一 基于 mapboxgl+threejs+react+ts 的 三维 webgis 实战系列教程: 后续将分享一些下面的功能: 基本项目搭建: threejs + mapboxgl 版 Hel ...
最新文章
- ubuntu下面搭建SolrCloud集群
- php邮件通知,邮件通知设置
- SharePoint 2010 沙盒解决方案以及 Visual Studio 2010 模板
- graylog2+syslog-ng+mongodb构建集中管理日志服务器 --转载
- 控件包含代码块(即 ),因此无法修改控件集合 (转自http://blog.csdn.net/wangchao1982/archive/2007/11/19/1892472.aspx)...
- 10-Qt6 QStringView
- 统计消息总数_和公牛一战,库里创三个记录,耀眼的还是三分球总数
- Hdu 4415 Assassin's Creed 【贪心】.cpp
- 10个适用于Java程序员的有用单元和集成测试工具
- python的数值类型_Python的数值类型
- 华为鸿蒙新机价格表,华为Mate30已确认:鸿蒙系统+巴龙5000,售价感人
- C++使用命名管道使用进程间通信
- c语言实验集成环境软件,TurboC for Windows集成实验与学习环境
- ubuntu(20.04)+linux内核(5.17.3)的config文件
- java 后端处理PDF图册
- PHP在线工具箱源码站长引流+在线工具箱源码+多款有趣的在线工具+一键安装
- php后台登录页,后台登录页面模板源码
- 既然彼此不能相濡以沫, 那就相忘于江湖吧.
- css实现图片自动渐变切换、element-plus 的修改el-table的(边框线为虚线、表头样式)
- bootstrap X-editable使用。