react+ts项目实战:如何使用withRouter?

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

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

const SystemSider = withRouter(class extends React.Component {
    render(){
        console.log(this.props, this.props.location.pathname.split('/')[1],this.props.location.pathname.split('/')[2])
        return (
            
                
                      公文管理  }>
                        收文登记
                        档案借阅
                        借阅管理
                        规章制度
                        质量管理
                        合同模版
                    
                      审批流程}>
                        我的申请
                        我的待办
                    
                
            
        )
    }  
});

 

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校验

react+ts项目实战:如何使用withRouter?_第1张图片

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

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

// @ts-ignore
@withRouter
class SystemSider extends React.Component<{}> {
    get injected() {
        return this.props as RouteComponentProps
    }

    render(){
        return (
            
                
                      公文管理  }>
                        收文登记
                        档案借阅
                        借阅管理
                        规章制度
                        质量管理
                        合同模版
                    
                      审批流程}>
                        我的申请
                        我的待办
                    
                
            
        )
    }  
};
export default SystemSider
// @ts-ignore
@withRouter
class SystemSider extends React.Component> {
    render(){
        console.log(this.props)
        return (
            
                {/** 这里要使用非空类型断言*/}
                
                      公文管理  }>
                        收文登记
                        档案借阅
                        借阅管理
                        规章制度
                        质量管理
                        合同模版
                    
                      审批流程}>
                        我的申请
                        我的待办
                    
                
            
        )
    }  
};
export default SystemSider

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

class SystemSider extends React.Component<{}> {
    get injected() {
        return this.props as RouteComponentProps
    }
    render(){
        console.log(this.props)
        return (
            
                
                      公文管理  }>
                        收文登记
                        档案借阅
                        借阅管理
                        规章制度
                        质量管理
                        合同模版
                    
                      审批流程}>
                        我的申请
                        我的待办
                    
                
            
        )
    }  
};
// @ts-ignore
export default withRouter(SystemSider)

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

你可能感兴趣的:(React,TypeScript)