React project framework based on webpack4

Time:2020-11-22

introduce

The framework introduces the react single page application built by WebPAC and integrates antd. Use webpack dev server to start local service and add hot update to facilitate development and debugging. Code cutting lazy loading using bundle loader
Manual build, no use of CLI, a large number of comments for beginners to understand the webpack learning, in-depth understanding of the react project

start-up

  git clone https://gitee.com/wjj0720/react-demo.git
  cd react-demo
  yarn
  yarn start

pack

  yarn build

directory structure

+node_modules
  -src
    +asset
    +Layout
    +pages
    +redux
    +utils
    +app.js
    +index.html
    +index.js
  .babelrc 
  package.json 
  postcss.config.js
  webpack.config.js  //Webpack configuration

Bundle loader is used for lazy loading

// webpack.config.js  to configure
  module: {
    rules: [
      {
        test: /\.bundle\.js$/,
        use: {
          loader: 'bundle-loader',
          options: {
            name: '[name]',
            lazy: true
          }
        }
      }
    ]
  }
  //Page import component
  import Home from "bundle-loader?lazy&name=[name]!./Home";

  //Component usage because component lazy loading is introduced in the form of asynchronous, so it can't be used directly in the form of tags on the page, so it needs to be encapsulated 
  import React, {Component} from 'react'
  import { withRouter } from 'react-router-dom'
  class LazyLoad extends Component {
    state = {
      LoadOver: null
    }
    componentWillMount() {
      this.props.Loading(c => {
        this.setState({
          LoadOver: withRouter(c.default)
        })
      })
    }
  
    render() {
      let {LoadOver} = this.state;
      return (
        Loadover? < loadover / >: < div > Load animation < / div >
      )
    }
  }
  export default LazyLoad

  //Excessive increase of loading animation through encapsulated lazy loading components
  <LazyLoad Loading={Home} />

Routing configuration

The framework is divided by modules, and the pages folder has route.js It is a module

//Through require.context Read the routing file under the module
  const files = require.context('./pages', true, /route\.js$/)
  let routers = files.keys().reduce((routers, route) => {
    let router = files(route).default
    return routers.concat(router)
  }, [])

  //Module routing file format
  import User from "bundle-loader?lazy&name=[name]!./User";
  export default [
    {
      path: '/user',
      component: User
    },
    {
      path: '/user/:id',
      component: User
    }
  ]

Introduction to Redux

//--- create--------
  //In order to avoid the action and reducer to switch back and forth between different files to create objects

  //Createreducer creates the writing format as a reducer recognized by rudex
  export function createReducer({state: initState, reducer}) {
    return (state = initState, action) => {
      return reducer.hasOwnProperty(action.type) ? reducer[action.type](state, action) : state
    }
  }

  //Create a page level store
  const User_Info_fetch_Memo = 'User_Info_fetch_Memo'
  const store = {
    //Initialization data
    state: {
      memo: 9,
      test: 0
    },
    action: {
      async fetchMemo (params) {
        return {
          type: User_Info_fetch_Memo,
          callAPI: {url: 'http://stage-mapi.yimifudao.com/statistics/cc/kpi', params, config: {}},
          payload: params
        }
      },
      ...
    },
    reducer: {
      [User_Info_fetch_Memo] (prevState = {}, {payload}) {
        console.log('reducer--->',payload)
        return {
          ...prevState,
          memo: payload.memo
        }
      },
      ...
    }
  }

  export default createReducer(store)
  export const action = store.action

  //Finally, it is combined in the module domain [of course, the module also has public data (see demo writing method under the home module)]
  import {combineReducers} from 'redux'
  import info from './Info/store'
  export default combineReducers({
    info,
    。。。
  })

  //In the final rudex folder store.js  Will go to all modules under the store.js   Form a big store, which is our final warehouse

  //Use------
  //First, in the app.js Associate store with app
  import { createStore } from 'redux'
  import { Provider } from 'react-redux'
  //Reduce is our ultimate goal
  import reducer from './redux/store.js'
  //Middleware of user asynchronous action
  import middleware from './utils/middleware.js'
  let store = createStore(reducer, middleware)
  <Provider store={store}>
    。。。
  </Provider>


  //Then the component calls only need to use the connect link when the component is exported
  import React, {Component} from 'react'
  import {connect} from 'react-redux'
  //Export action from page level store
  import {action} from './store'

  class Demo extends Component {
    const handle = () => {
      //Trigger action
      this.props.dispatch(action.fetchMemo({}))
    }
    render () {
      console.log(this.props.test)
      return <div onClick={this.handle}>ss</div>
    }
  }
  export default connect(state => ({
    test: state.user.memo.test
  }) )(demo)

About Redux Middleware

//Action middleware is better than Redux middleware
  //The execution time of middleware is executed before each action is triggered

  // 
  import { applyMiddleware } from 'redux'
  import fetchProxy from './fetchProxy';

  //Middleware is three nested functions. The first input parameter is the entire store, and the second is the store.dispatch  The third is the action triggered this time 
  //The simple encapsulation middleware does not deal with the request failure too much in order to deal with the page with the item error handling mechanism
  const middleware = ({getState}) => next => async action => {
    //The aciton has not been executed at this time 
    const {type, callAPI, payload} = await action
    //Return action directly without asynchronous request
    if (!callAPI) return next({type, payload})
    //Request data
    const res = await fetchProxy(callAPI)
    //Request data失败 提示
    if ( res.status  !== 200)  return  console.log ('network error! )
    //Data returned successfully
    return next({type, payload: res.data})
  }
  export default applyMiddleware(middleware)

Recommended Today

Array of algorithms — sum of three numbers

Sum of three numbers difficultysecondary Here is an array of N integersnums, judgmentnumsAre there three elements a, B, C in a such that a + B + C = 0? Please find all triples that satisfy the condition and do not repeat.be careful:The answer cannot contain duplicate triples. Example:Given array nums = [- 1, 0, […]