示例是使用antd组件库作测试的,有react-router和redux穿插,项目比较
基本效果如图
创建项目
> npx create-react-app react-typescript-demo --typescript
项目结构:
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( , document.getElementById('root'));
ReactDOM.render(
,
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-PWA
serviceWorker.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 {
// constructor(props: Props){
// super(props);
// }
render() {
console.log(this.props.cName);
return (
page a
page b
Header
{this.props.cName}
)
}
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 (
)
}
}
export default A;
page/b.tsx
import React, {Component} from 'react';
import { Avatar } from 'antd';
class B extends Component {
render() {
return (
);
}
}
export default B;