前言
vue
写的不少了,想了解一下react
,再加上大家都说typescript
很香,所以用react + typescript
写个小的demo项目了解一下。因为项目主要为了练一下各种技术的配合使用,所以结构和代码上实现的比较随意,有兴趣的学习react的新人朋友们也就酌情浏览就好了😄,我也是正在学习react,大家可以留言讨论哈。
项目地址
https://github.com/18sby/disorganizedApp
说明
在配置react子路由跳转的时候卡了两天,现在搞定了,先反思一下原因
- 读英文文档能力有待提升:提升方式就是「硬读」,发现读着读着不知不觉也可以提高
- 要精读文档,不能一目十行
安装依赖
安装依赖( 因为是在typescript中使用的,所以也在开发环境中安装了一些与typescript相关的依赖 )
npm i react-router react react-router-dom react-router-dom react-dom --save
npm i typescript awesome-typescript-loader @types/react @types/react-dom @types/react-router-dom --save-dev
最简单配置子路由(不一定是最优)
看下要实现的效果
点击左侧不同的菜单,在右侧区域展示不同的组件(虽然不用子路由也能做),但这里是为了学习一下子路由的使用
主要用到 react-router-dom 中的三个组件
BrowerRouter/HashRouter
Link
Route
BrowerRouter/HashRouter:这两种的区别暂且不说,官方的说明,这个组件只是作为容器,我们可以把他大致理解为一个空标签<></>
,而与空标签唯一的区别就是,它是用来包裹路由的。
下面的内容用Router
代替 BrowerRouter/HashRouter
来写
Link:可以理解为一个a
标签来使用
Route:个人理解,作为即将匹配路由的组件显示区域
因为文档的使用规范是:要把Link
和 Route
放在一个Router
容器内,所以最简单的方式就是在入口文件中用Router
标签包裹住首页 HomePage
// 项目的入口文件
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import { BrowserRouter as Router } from 'react-router-dom';
import HomePage from './pages/home';
ReactDOM.render(
<Router>
<HomePage author='bart' />
</Router>,
document.getElementById( 'app' )
)
看一下首页配置子路由的代码
使用Link
和Route
的地方已标记注释
import * as React from 'react';
import { IHomePageProps, IHomePageState } from './types';
import { Row, Col, Menu, Icon, Card, PageHeader } from 'antd';
const { SubMenu } = Menu;
import './styles.scss';
import SpeechTechnology from '../../components/speech';
import CharacterRecognition from '../../components/character';
import TextQueryCmpt from '../../components/general/textquery/index';
import TestPage from '../../components/testPage';
import { Link, Route } from 'react-router-dom';
class HomePage extends React.Component<IHomePageProps, IHomePageState> {
constructor(props: IHomePageProps) {
super(props);
const { author } = props;
this.state = {
leftMenu: [
{
key: 'speechTechnology',
value: '语音技术'
},
{
key: 'characterRecognition',
value: '文字识别'
},
{
key: 'imageRecognition',
value: '图像识别'
}
],
leftMenuKeys: [],
selectedMenu: 'imageRecognition',
}
}
public handleClick = (e: any) => {
console.log( '点击的菜单', e, this );
const map: any = {
'speechTechnology': SpeechTechnology,
'characterRecognition': CharacterRecognition
}
this.setState({
selectedMenu: e.key
})
}
public render() {
const { leftMenu, leftMenuKeys } = this.state;
leftMenu.forEach(menu => {
leftMenuKeys.push( menu.key );
});
return (
<div className="homepage-container">
<PageHeader
title="专治无聊"
subTitle="无聊就来查查吧"
/>
<Row>
<Col span={6}>
<Menu
onClick={this.handleClick}
style={{ width: 256 }}
defaultSelectedKeys={ [''] }
defaultOpenKeys={ leftMenuKeys }
mode="inline"
>
<SubMenu
key="all"
title={
<span>
<Icon type="mail" />
<span>所有分类</span>
</span>
}
>
{/* 设置跳转路由的标签 */}
{ leftMenu.map(el => {
return (
<Menu.Item key={ el.key } onClick={ () => { this.handleClick } }>
<Link to={`/${el.key}`}>{ el.value }</Link>
</Menu.Item>
)
}) }
</SubMenu>
</Menu>
</Col>
<Col offset={2} span={16}>
{/* 显示子路由组件的区域 父路由为「/」 */}
<Route exact path="/speechTechnology" component={ SpeechTechnology } />
<Route exact path="/characterRecognition" component={ CharacterRecognition } />
<Route path="/characterRecognition/test" component={ TextQueryCmpt } />
</Col>
</Row>
</div>
);
}
}
export default HomePage;