示例是使用antd组件库作测试的,有react-router和redux穿插,项目比较

基本效果如图

项目结构:

react-typescript-demo  node_modules  public    favicon.ico    index.html    manifest.json  src    pages      a.tsx      b.tsx    store      index.js    App.css    App.test.tsx    App.tsx    index.css    index.tsx    logo.svg    react-app-env.d.ts    serviceWorker.ts  .gitignore  package.json  README.md  tsconfig.json  yarn.lock

package.json

{  "name": "react-typescript-demo",  "version": "0.1.0",  "private": true,  "dependencies": {    "@types/jest": "24.0.13",    "@types/node": "12.0.1",    "@types/react": "16.8.17",    "@types/react-dom": "16.8.4", // @types/react和@types/react-dom是在create-react-app创建项目时生成的    "antd": "^3.18.1",    "react": "^16.8.6",    "react-dom": "^16.8.6",    "react-redux": "^7.0.3",    "react-router": "^5.0.0",    "react-router-dom": "^5.0.0",    "react-scripts": "3.0.1",    "redux": "^4.0.1",    "typescript": "3.4.5"  },  "scripts": {    "start": "react-scripts start",    "build": "react-scripts build",    "test": "react-scripts test",    "eject": "react-scripts eject"  },  "eslintConfig": {    "extends": "react-app"  },  "browserslist": {    "production": [      ">0.2%",      "not dead",      "not op_mini all"    ],    "development": [      "last 1 chrome version",      "last 1 firefox version",      "last 1 safari version"    ]  },  "devDependencies": { // typescript版本的文件依赖    "@types/react": "^16.8.17",    "@types/react-redux": "^7.0.9",    "@types/react-router": "^5.0.0",    "@types/react-router-dom": "^4.3.3"  }}

index.tsx 主文件

import React from 'react';import ReactDOM from 'react-dom';import './index.css';import App from './App';import * as serviceWorker from './serviceWorker';// 引入antd相关import { LocaleProvider } from 'antd';import zhCN from 'antd/lib/locale-provider/zh_CN';import 'antd/dist/antd.css';import { BrowserRouter } from 'react-router-dom';import {Provider} from "react-redux";import store from './store';// ReactDOM.render(<App />, document.getElementById('root'));ReactDOM.render(    <Provider store={store}>        <LocaleProvider locale={zhCN}>            <BrowserRouter>                <App/>            </BrowserRouter>        </LocaleProvider>    </Provider>,     document.getElementById('root'));// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://bit.ly/CRA-PWAserviceWorker.unregister();

App.tsx

import React, {Component} from 'react';import './App.css';import { Switch, Route } from 'react-router';import { NavLink } from 'react-router-dom';import { Layout } from 'antd';import A from './pages/a';import B from './pages/b';import { Dispatch } from 'redux';import { connect } from "react-redux";const { Header, Footer, Sider, Content } = Layout;interface Props {  cName: string,  changeName?: any}interface State {  name: string}class App extends Component<Props> {  // constructor(props: Props){  //   super(props);  // }  render() {    console.log(this.props.cName);    return (      <Layout>        <Sider>          <ul>            <li><NavLink to="/a" activeClassName="selected">page a</NavLink></li>            <li><NavLink to="/b" activeClassName="selected">page b</NavLink></li>          </ul>        </Sider>        <Layout>          <Header>Header</Header>          <Content>            <Switch>              <Route exact path="/a" component={A}/>              <Route path="/b" component={B}/>              <Route component={A}/>            </Switch>            <p style={{fontSize: 24, color: '#f00'}}>{this.props.cName}</p>          </Content>          <Footer>Footer</Footer>        </Layout>      </Layout>    )  }  componentDidMount() {    setTimeout(() => {      this.props.changeName({        name: 'jack'      });    }, 1500);  }}// 把state放到props里function mapStateToProps(state: State) {  return {    cName: state.name  }}// 把方法放到props里function mapDispatchToProps(dispatch: Dispatch) {  return {    changeName: (payload: object)=>dispatch({type: 'CHANGE_NAME', payload: payload})  }}export default connect(mapStateToProps, mapDispatchToProps)(App);

store/index.js

import {createStore} from 'redux';function toDo(state, action) {  state = state || {name: 'tom'};  switch (action.type) {    case 'CHANGE_NAME':      return {...state, ...action.payload};    default:      return state;  }}let store = createStore(toDo);export default store;

page/a.tsx

import React, {Component} from 'react';import { Button } from 'antd';class A extends Component {  render() {    return (      <div>        <Button type="primary">Primary</Button>        <Button>Default</Button>        <Button type="dashed">Dashed</Button>        <Button type="danger">Danger</Button>        <Button type="link">Link</Button>      </div>    )  }}export default A;

page/b.tsx

import React, {Component} from 'react';import { Avatar } from 'antd';class B extends Component {  render() {    return (      <div>        <div>          <Avatar size={64} icon="user" />          <Avatar size="large" icon="user" />          <Avatar icon="user" />          <Avatar size="small" icon="user" />        </div>        <div>          <Avatar shape="square" size={64} icon="user" />          <Avatar shape="square" size="large" icon="user" />          <Avatar shape="square" icon="user" />          <Avatar shape="square" size="small" icon="user" />        </div>      </div>    );  }}export default B;