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
  • 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