WLM-TypeScript-React-Starter
Wlm-typescript-react-starter is a TypeScript Starter project that integrates React + react-router + Redux + redux-thunk. The TypeScript project is designed to provide Web application developers with an “out-of-the-box” TypeScript project that they can download and use to write large, complex React applications.
TypeScript 3.0 practices in complex React applications
Install
$ git clone https://github.com/welearnmore/WLM-TypeScript-React-Starter.git
$ cd WLM-TypeScript-React-Starter
$ yarn
$ npm startCopy the code
Use a browser to access the local file index.html. (See the scripts field of package.json for more commands.)
Version
Compilation environment:
- Node. Js > 8.0
- typescript > 3
- git
- yarn
- Support editorconfig
- Support tslint
The React series:
"Prop - types", "^ 15.6.2", "react" : "^ 16.4.2", "the react - dom" : "^ 16.4.2", "the react - redux" : "^ 5.0.7", "the react - the router - dom" : "^ 4.3.1", "story" : "^ 4.0.0", "the story - thunk" : "^ 2.3.0." "Copy the code
The directory structure
The top-level directory structure is as follows:
- SRC Project source file
- Typings Custom declaration
- Dist compiled directory
The SRC directory structure is as follows:
- Components Reusable components between different pages (self-created)
- Pages page-level components
- [Home] User-defined directory
- Flow redux related
- Components Reusable components for this page (self-created)
- Index.tsx page entry
- Style. Less style entry
- [Home] User-defined directory
- Global Redux Store configuration and Global Reducers
- Index. The TSX entrance
use
Create a directory in Pages, let’s say it’s called Home (which is the developer’s convention), then create index.tsx, style.less file and flow directory (create actions. Ts, constants.ts, Mainpagereducers.ts), if you don’t use redux, you don’t have to create a flow directory.
Write entry index.tsx:
import * as React from "react"; import { connect } from "react-redux"; import * as actions from "./flow/actions"; import * as TYPES from "./flow/types"; import { IStoreState } from ".. /.. /global/types"; import { Header } from "./components/Header"; import "./style.less"; const localImage = require("@/assets/welearnmore.png"); const onLineImage: string = "http://images.w3crange.com/welearnmore.png"; class HomeComponent extends React.Component<TYPES.IHomePageProps, TYPES.IHomePageState> { constructor(props: TYPES.IHomePageProps) { super(props); this.state = { name: "", }; } public actionDataSync = () => { this.props.dataSync(); } public actionDataAsync = () => { this.props.dataAsync("icepy"); } public setName = () => { this.setState({ name: "icepy", }); } public logReactRouterObj = () => { // console.log(this.props.history); } public render() { const { homePage, global } = this.props; const { syncId, asyncId } = homePage; const { globalSyncId } = global; const { name } = this.state; return ( <div className="container"> <Header localImageSrc={localImage} onLineImageSrc={onLineImage} /> <div className="buttons"> <button onClick={this.actionDataSync}> dataSync action </button> <button onClick={this.actionDataAsync}> dataAsync action </button> <button onClick={this.setName}> setState name </button> <button onClick={this.logReactRouterObj}> react-router object </button> </div> <div className="contents"> <p> syncId: {syncId} </p> <p> asyncId: {asyncId} </p> <p> setState name: {name} </p> <p> react-router object: open Chrome Dev Tool console.log; </p> <p> global Sync Id: {globalSyncId} </p> </div> </div> ); } } const mapStateToProps = (state: IStoreState) => { const { homePage, global } = state; return { homePage, global, }; }; export const HomePage = connect(mapStateToProps, actions)(HomeComponent);Copy the code
Write the reducers:
import { IAction } from "@/store/types"; import * as CONST from "./constants"; import * as TYPES from "./types"; Const initState: TYPES. IHomePageStoreState = {asyncId syncId: "default" : "default",}; export function homeReducers(state = initState, action: IAction): TYPES.IHomePageStoreState { const { type, payload } = action; switch (type) { case CONST.SYNC_DATA: return { ... state, syncId: payload.data }; case CONST.ASYNC_DATA: return { ... state, asyncId: payload.data }; default: return { ... state }; }}Copy the code
Introduce reducers in the store:
import { createStore, applyMiddleware, combineReducers, compose } from "redux";
import thunk from "redux-thunk";
import { homeReducers } from "@/pages/Home/flow/homeReducers";
import { globalReducers } from "./globalReducers";
/* eslint-disable no-underscore-dangle, no-undef */
const composeEnhancers = (window as any) && (window as any).REDUX_DEVTOOLS_EXTENSION_COMPOSE || compose;
const reducer = combineReducers({
global: globalReducers,
homePage: homeReducers,
});
export const configureStore = () => createStore(
reducer,
composeEnhancers(applyMiddleware(thunk)),
);Copy the code
LICENSE
GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007