This example of the template of the three big guy to write a small volume, before using JS to write again, recently in the ts, tried to write a recommendation page. The demo address

1. Initialize the project and configure less

First use React’s official scaffolding to create your project

npx create-react-app demo --typescript
cdDemo NPM run eject eject webpack, Babel and other related configurations. Note that this operation is irreversibleCopy the code

Open the webpack.config.js file in the config folder. In this file, the getStyleLoaders function takes two arguments: the Options passed in to the CSS-Loader and the optional loader to add. Finally, the configured Loader array is returned. We add the following code:

const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
Copy the code

Then in the oneOf array, add the following code:

            {
              test: lessRegex,
              exclude: lessModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  // modules: true, //// access styles using modulessourceMap: isEnvProduction && shouldUseSourceMap,
                },
                "less-loader"
              ),
              sideEffects: true}, {test: lessModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  // modules: true,
                  getLocalIdent: getCSSModuleLocalIdent,
                },
                "less-loader"),},Copy the code

Modules: true, if less is used in the file:

import styles from './style.less';
<div className={styles.div}></div>
Copy the code

If this item is not specified, use the CSS as follows:

import './style.less';
<div className='div'></div>
Copy the code

Note that if modules: True is not configured, the CSS styles from third-party libraries should be introduced in the.less file. For example, if you want to introduce swiper’s style to a caroute map component, you would introduce the following code to the.less file that the component imports:

@import '.. /.. /.. /node_modules/swiper/css/swiper.css';
Copy the code

Finally, add the following code to the react-app-env.d.ts file in the SRC directory to use less

declare module "*.less" {
  const less: any;
  export default less;
}
Copy the code

Second, the react to the router

HashRouter and BrowserRouter

The Hash attribute in front of a HashRouter is a readable and writable string. This string is the anchor part of the URL (starting with #), that is, its path contains #, which is of the form IP :port/#/xx. The requested resource path is always/regardless of the path after #. Similar to index.html, the back-end API interface does not conflict with/and can be easily deployed without separating the front and back ends.

BrowserRouter is the H5 history API, which is not compatible with IE9 and requires Web Server support. Its request paths are all in the form of IP :port/ XXX.

BrowserRouter can pass arbitrary parameters to communicate between components while HashRouter cannot (unless you manually concatenate URL strings), so it is generally used with Redux to communicate between components. HashRouter does not require Web Server support and is often used to support older browsers.

Use of BrowserRouter

import { createBrowserHistory } from "history";
<Router history= {history}>
    <Route path="/" component={Layout}></Route>
</Router>
Copy the code

Connect react-redux to immer

Redux Chinese document

Create a store file, introduce the reducer of the component, use combineReducers to synthesize all the reducer into a large reducer; ApplyMiddleware changes the Actions => Reducer process from Redux to Action => Middleware => Reducer. We can use applyMiddleware to implement asynchronous actions, log printing, error reporting, and more. The specific code is as follows:

import { createStore, compose, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import recommendReducer from './page/Recommend/store/reducer';

const Reducer = combineReducers({
  recommend: recommendReducer,
});

export const Store = createStore(
  Reducer,
  compose(applyMiddleware(thunk))
);

export type initState = ReturnType<typeof Reducer>;
Copy the code

The initState shown here is the initial state in reducer. Different from the JS version, we put its definition in specific Reducer. You can use it in the component’s mapStateToProps method:

const mapStateToProps = (state: initState) => ({
  bannerList: state.recommend.bannerList,
  recommendList: state.recommend.recommendList,
});
Copy the code

If it’s too much trouble, you can just use any.

The next step is to inject the store globally. In the index file, we need to use the Provider component.

Provider is the context attribute of the React component. The source code is as follows:

class Provider extends Component {
  getChildContext() {
    return {
      store: this.props.store
    };
  }
  render() {
    return this.props.children;
  }
}

Provider.childContextTypes = {
  store: React.PropTypes.object
}
Copy the code

In the above code, store is placed above the context object context. And then the child component can get from the context to the store;

The code for index is as follows:

const history = createBrowserHistory();
ReactDOM.render(
  <Provider store={Store}>
    <Router history= {history}>
      <Route path="/" component={Layout}></Route>
    </Router>
  </Provider>,
  document.getElementById("root"));Copy the code

immer

There are many explanations about IMmer on the Internet, so I will not repeat them here, but paste the code directly and use it in reducer

import * as actionTypes from './actionType';
import produce from 'immer';
import { RecommendStateType } from './data';

const defaultState: RecommendStateType = {
  bannerList: [],
  recommendList: [],
}

export default (state = defaultState, action: any) => {
  return produce(state, draft => {
    switch (action.type) {
      case actionTypes.CHANGE_BANNER:
        draft.bannerList = action.data;
        break;
      case actionTypes.CHANGE_RECOMMEND_LIST:
        draft.recommendList = action.data;
        break;
      default:
        returnstate; }})}Copy the code

Four,

In general, writing in Redux can be a bit cumbersome, so there are many frameworks in the community based on redux encapsulation, and I recommend DVA. Three big guy’s small volume, I write js version is to use DVA. Of course, as one of my classmates said, in the interview, they ask you about Redux, they don’t ask you about DVA, so it’s kind of a review of Redux.

The author is still a front end small sprout new, unavoidably can have careless mistake, welcome big guys to give directions!