Create a project

  • Install React scaffolding

    npm install -g create-react-app
    Copy the code
  • Create a project

    # app is the project name
    create-react-app app
    Copy the code

  • Or skip the above two steps and just use it

    npx create-react-app app
    
    Create a typescript project
    npx create-react-app app --template typescript
    Copy the code

  • Start the project

    cd app
    npm start
    Copy the code

  • The project is created in the following directory


Use the Ant Design UI component library

Install Ant Design:API Docs

No permission please use sudo
npm install antd --save
# or
cnpm install antd --save
cnpm i antd -S
Copy the code

Configure Ant Design to load on demand:The configuration document

usebabel-plugin-import(Recommended).

  1. Expose the configuration file first

    npm run eject
    Copy the code

    NOTE: Create React App 2+ supports TypeScript, Sass, CSS Modules and more without ejecting: Reactjs.org/blog/2018/1…

    The operation is permanent and irreversible.

    If you do not want to expose the configuration, you can refer to overwriting CRA’s Webpack configuration to implement Antd on demand loading and introduce Less without using eject

  2. Configure Babel in package.json (with babel-plugin-import installed)

    Error: Cannot find module ‘babel-plugin-import’ Babel-plugin-import needs to be installed

    npm install babel-plugin-import --save-dev
    # or
    cnpm install babel-plugin-import --save-dev
    cnpm i babel-plugin-import -D
    Copy the code

    The Babel configuration is as follows

    "babel": {
       "presets": [
         "react-app"]."plugins": [["import",
           {
             "libraryName": "antd"."libraryDirectory": "es"."style": true}}]]Copy the code

    To import styles using the style configuration of babel-plugin-import, change the configuration value from ‘style’: ‘CSS’ to ‘style’: true, which will import less files.

Configure Ant Design Chinese language (default copy is English) :The configuration document

Configure it in the entry file index.js

import { ConfigProvider } from 'antd';
import zh_CN from 'antd/lib/locale-provider/zh_CN';
import moment from 'moment';
import 'moment/locale/zh-cn';

moment.locale('zh-cn');
Copy the code

For a list of languages, see Ant Design Internationalization

You also need to wrap the root component with the ConfigProvider component:

<ConfigProvider locale={zhCN}>
  <App />
</ConfigProvider>
Copy the code

Install and Configure less Preprocessor && Configure Ant Design theme:The configuration document

NPM install less less-loader --save-dev or CNPM install less less-loader --save-dev CNPM I less less-loader -dCopy the code

Configure less in config/webpack.config.js:

{
  test: /\.less$/,
  use: [
    {
      loader: 'style-loader'}, {loader: 'css-loader'.// translates CSS into CommonJS
    },
    {
      loader: 'less-loader'.// compiles Less to CSS
      options: {
        lessOptions: { // If you are using less-loader@5 please spread the lessOptions to options directly
          modifyVars: {
            // 'primary-color': '#1DA57A',
            // 'link-color': '#1DA57A',
            // 'border-radius-base': '2px',
            // or
            // hack: `true; @import "your-less-file-path.less"; `, // Override with less file
          },
          javascriptEnabled: true},},},],},Copy the code

The configuration location is as follows:

The Ant Design website provides configurable items:

@primary-color: #1890ff; // Global dominant color
@link-color: #1890ff; / / the link color
@success-color: #52c41a; / / success
@warning-color: #faad14; / / warning color
@error-color: #f5222d; / / error
@font-size-base: 14px; / / the main font size
@heading-color: rgba(0.0.0.0.85); / / title
@text-color: rgba(0.0.0.0.65); //
@text-color-secondary : rgba(0.0.0.45.); // Subtext
@disabled-color : rgba(0.0.0.25.); / / failure
@border-radius-base: 4px; // Assembly/floating layer fillet
@border-color-base: #d9d9d9; / / border color
@box-shadow-base: 0 2px 8px rgba(0.0.0.0.15); // Float shadow
Copy the code
  • Install CSS resets: normalize.css

    npm install normalize.css --save
    # or
    cnpm install normalize.css --save
    cnpm i normalize.css -S
    Copy the code

    After the installation is complete, import it in the entry file index.js.

    import 'normalize.css';
    Copy the code

Install and configure the AXIOS and QS

npm install axios qs --save
# or
cnpm install axios qs --save
cnpm i axios qs -S
Copy the code

Configure request interceptors and response interceptors: service.js:

import axios from 'axios';

const service = axios.create({
  // baseURL: window.location.origin,
  timeout: 30000
  /*headers: { 'Cache-Control': 'no-cache' }*/
}); /* Request interceptor */
service.interceptors.request.use(
  (config) = > {
    // Set the request to configReturn config;
  },
  (err) = > {
    console.error('Request error occurred', err);
    return Promise.reject(err); });/* Response interceptor */
service.interceptors.response.use(
  (res) = > {
    // Configure the response interceptor here
    return res;
  },
  (err) = > {
    console.error('An error occurred in response', err);
    return Promise.reject(err); });export default service;
Copy the code

Configure the API call method:

// Introduce the AXIos configuration
import service from './service';
import qs from 'qs';

/ / post request
export function apiPost(data = {}) {
  return service({
    url: 'interface url'.method: 'post'.data: qs.stringify(data)
  });
}

/ / get request
export function apiGet(params = {}) {
  return service({
    url: 'interface url'.method: 'get'.params: params
  });
}
Copy the code

Configuring cross-domains:Docs

The configuration is already exposed by the NPM Run eject in the previous configuration

npm install http-proxy-middleware --save
# or
cnpm i http-proxy-middleware -S
Copy the code

Create setupproxy.js under SRC

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:5000'.changeOrigin: true,})); };Copy the code

Install and configure a react-router:API Docs

npm install react-router-dom --save
# or
cnpm install react-router-dom --save
cnpm i react-router-dom -S
Copy the code

Create a separate router.js (or write the route view in the entry file index.js)

import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import YourComponent from 'your-component-path';

export default function () {
  return (
    <Router>
      <Route path='/' component={YourComponent} />
    </Router>
  );
}
Copy the code

Then use this router-js reference in index.js:

import Router from './path/router.js';

export default function Index() {
  return <Router />;
}
Copy the code

If you want to add router.js to your index.js file, you need to add router.js to your index.js file. If you want to add router.js to your index.js file, you need to add router.js to your index.js file.

Install and configure reduxreact-redux Docs,redux Docs,Chinese Docs

npm install redux redux-thunk react-redux --save
# or
cnpm install redux redux-thunk react-redux --save
cnpm i redux redux-thunk react-redux -S
Copy the code

Create a redux folder under SRC and use it as a directory to configure redux:

Actions: Put the actions files that are configured for different function modules in this directory. Reducers: Put the reducers files that are configured for different function modules in this directory. Reducers.js: Combine all reducers: store.js: configuration file for Redux: types.js: Store the type attribute values required in ActionsCopy the code

File code: types.js:

export const MYTODO = 'MYTODO';
export const MYLIST = 'MYLIST';
export const OTHERTODO = 'OTHERTODO';
export const OTHERLIST = 'OTHERLIST';
Copy the code

myReducer.js:

import { MYTODO, MYLIST } from '.. /types';
const initState = {
  myTodos: [].list: []
  / /... etc.
};
export default function (state = initState, action) {
  switch (action.type) {
    case MYTODO:
      return {
        ...state,
        myTodos: action.payload
      };
    case MYLIST:
      return {
        ...state,
        list: action.payload
      };
    default:
      returnstate; }}Copy the code

myActions.js:

import { MYTODO, MYLIST } from '.. /types';

export const myTodos = (params) = > (dispatch, getState) = > {
  // const { myState, otherState } = getState();
  dispatch({
    type: MYTODO,
    payload: params
  });
};
export const handleMyList = (params) = > (dispatch, getState) = > {
  // const { myState, otherState } = getState();
  dispatch({
    type: MYLIST,
    payload: params
  });
};
Copy the code

otherReducer.js:

import { OTHERTODO, OTHERLIST } from '.. /types';
const initState = {
  otherTodos: [].list: []
  / /... etc.
};
export default function (state = initState, action) {
  switch (action.type) {
    case OTHERTODO:
      return {
        ...state,
        otherTodos: action.payload
      };
    case OTHERLIST:
      return {
        ...state,
        list: action.payload
      };
    default:
      returnstate; }}Copy the code

otherActions.js:

import { OTHERTODO, OTHERLIST } from '.. /types';

export const otherTodos = (params) = > (dispatch, getState) = > {
  // const { myState, otherState } = getState();
  dispatch({
    type: OTHERTODO,
    payload: params
  });
};
export const handleOtherList = (params) = > (dispatch, getState) = > {
  // const { myState, otherState } = getState();
  dispatch({
    type: OTHERLIST,
    payload: params
  });
};
Copy the code

reducers.js:

import { combineReducers } from 'redux';
import myReducer from './reducers/myReducer';
import otherReducer from './reducers/otherReducer';

export default combineReducers({
  myState: myReducer,
  otherState: otherReducer
});
Copy the code

store.js:

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducers from './reducers';

const initState = {};
const middleware = [thunk];

const composeEnhancers =
  typeof window= = ='object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
    : compose;

const enhancer =
  process.env.NODE_ENV === 'development'? composeEnhancers(applyMiddleware(... middleware)) : applyMiddleware(... middleware);export const store = createStore(reducers, initState, enhancer);
Copy the code

The basic configuration of Redux is complete, here is the method to call:

import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { myTodos, handleMyList } from './path/redux/actions/myActions';

function MyTodosComponent() {
  useEffect(() = > {
    // Use this.props to access state
    console.log(this.props.myTodos);
    console.log(this.props.list);
    / / call the actions
    const todos = [
      {
        id: 1.todo: 'say hello world'}];this.props.myTodos(todos);
    const list = [
      {
        id: 1.text: 'test'}];this.props.handleMyList(list); } []);return (
    <div>
      {this.props.todos.map((item, index) => {
        return (
          <div>
            id:{item.id}, todo:{item.todo}
          </div>
        );
      })}
    </div>
  );
}
// Type check
MyTodosComponent.propTypes = {
  myTodos: PropTypes.array.isRequired,
  list: PropTypes.array.isRequired
};
// Bind the state in redux to the props of the component
const mapStateToProps = (state) = > {
  const { myTodos, list } = state.myState;
  return {
    myTodos,
    list
  };
};
// Combine redux with components to enable the component to access state and actions in props
export default connect(mapStateToProps, {
  myTodos,
  handleMyList
})(MyTodosComponent);
Copy the code