示例是使用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;