Introduction to react practice

Time:2022-5-10

Welcome to my blog:Introduction to react

Before writing this article, I had been in contact with react for more than half a year. After the initial study of react, it was officially applied to the project. At that time, I wanted to write and share some of my ideas, but I didn’t know how to write articles. Moreover, there was not enough time, so I put it aside.

This article is relatively basic without in-depth analysis, which is despised by the great gods. No more nonsense, so let’s get to the point.

brief introduction

First of all, I want to introduce react. All the friends who read this article must have some knowledge about react, but for the newcomers who have just come into contact, I will briefly introduce it here. Then there are some introductions and explanations about using react to build a simple single page application (SPA instead of single page application below).

About react

React originated from Facebook’s internal project. Because the company was not satisfied with all JavaScript MVC frameworks on the market, it decided to write one for instagram website. After making it, I found that this set of things is very easy to use, and it was opened in May 2013. (See this for more information

characteristic:

  • Just UI

  • Virtual DOM: minimize interaction with DOM (similar to using jQuery to manipulate DOM)

  • Unidirectional data flow: greatly reduces the use of duplicate code

Componentization:

  • Composable: a component is easy to use with other components or nested inside another component. If another component is created inside a component, the parent component owns the child components it creates. Through this feature, a complex UI can be divided into multiple simple UI components

  • Reusable: each component has independent functions and can be used in multiple UI scenarios

  • Maintainable: each small component only contains its own logic, which is easier to understand and maintain

Life cycle:

  • Mounting: real DOM inserted

  • Updating: being re rendered

  • Unmounting: removed from real DOM

React provides two processing functions for each state. The will function is called before entering the state, and the did function is called after entering the state. There are five processing functions in total for the three states.

  • componentWillMount()

  • componentDidMount()

  • componentWillUpdate(object nextProps, object nextState)

  • componentDidUpdate(object prevProps, object prevState)

  • componentWillUnmount()

In addition, react also provides processing functions for two special states.

  • Componentwillreceiveprops (object nextprops): called when a loaded component receives a new parameter

  • Shouldcomponentupdate (object nextprops, object nextstate): called when the component judges whether to re render

Topic

So let’s get to the point and spend some time writing a simple spa, which is also a relatively complete react skeleton, but it doesn’t include testing (you can see the tutorial of testing)this), the relevant source code can be viewedreact-start-kit

Next, let’s look at what we need to build this project:

  • react

  • redux

  • webpack

  • react-router

  • ant design

  • babel

There are still some not listed. See the source code of the warehouse for detailspackage.json。 The detailed introduction will list some articles I have read or official introduction at the end of the article.

Configuration item

Webpack

When it comes to the construction of react project, we have to mention the artifact of webpack. There are many construction tools, such as grunt, gulp and brunch. Compared with these construction tools, webpack feels that it coincides with react, especiallyreact-hot-loaderSuch artifact (hot loading) makes webpack the most mainstream react construction tool.

The features and introduction of webpack will not be repeated here. We can see the function of webpack from the following figure:

Next, let’s look at webpack from the project code.

entry: {
  app: [__dirname + '/src/index'],
},
output: {
  path: __dirname + '/_dist',
  filename: '[name]_[hash].js',
}

This part mainly specifies the import and export documents.entryAs the entry document of the project;outputAs an exit after file compilation, wherepathRepresents the path of the output,filenameRepresents the file name, and[name]_[hash]It ensures that there will be no cache in the browser (that is, the effect will not take effect after modifying the file).

module: {
  loaders: [{
    test: /\.js$/,
    loaders: ['babel'],
    exclude: /node_modules/,
  }, {
    test: /\.css$/,
    loaders: ['style', 'css'],
    include: /components/,
  }, {
    test: /\.(jpe?g|png|gif|svg|ico)/i,
    loader: 'file',
  }, {
    test: /\.(ttf|eot|svg|woff|woff2)/,
    loader: 'file',
  }, {
    test: /\.(pdf)/,
    loader: 'file',
  }, {
    test: /\.(swf|xap)/,
    loader: 'file',
  }],
}

This part will help us deal with different types of files, includingtestIs the suffix of the file,loadersIt’s a translator,includeIs the directory of the specified file,excludeIs to exclude a directory. We can see that all.jsFiles will be translated through Babel, that is, ES6 + syntax used in the project will be translated into Es5 code recognized by the browser through Babel.

Finally, the configured config is as follows:

var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    app: [__dirname + '/src/index'],
  },
  output: {
    path: __dirname + '/_dist',
    filename: '[name]_[hash].js',
  },
  resolve: {
    root: [
      __dirname + '/src',
      __dirname + '/node_modules',
      __dirname,
    ],
    extensions: ['', '.js'],
  },
  module: {
    loaders: [{
      test: /\.js$/,
      loaders: ['babel'],
      exclude: /node_modules/,
    }, {
      test: /\.css$/,
      loaders: ['style', 'css'],
      include: /components/,
    }, {
      test: /\.(jpe?g|png|gif|svg|ico)/i,
      loader: 'file',
    }, {
      test: /\.(ttf|eot|svg|woff|woff2)/,
      loader: 'file',
    }, {
      test: /\.(pdf)/,
      loader: 'file',
    }, {
      test: /\.(swf|xap)/,
      loader: 'file',
    }],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: __dirname + '/src/index.html',
      favicon: __dirname + '/src/favicon.ico',
      inject: false,
    }),
  ],
};

Express server startup

Node. JS web application development framework express, as the web server of the project, has node Students with JS development experience should be familiar with it, and I won’t repeat it here.

The final startup code is as follows:

var express = require('express');
var webpack = require('webpack');
var webpackConfig = require('./webpack.development');

var app = express();
var compiler = webpack(webpackConfig);

app.use(require('webpack-dev-middleware')(compiler, {
  stats: {
    colors: true,
  },
}));

app. use(require('webpack-hot-middleware')(compiler)); // Thermal loading

app. Listen (process. Env. Port, function (ERR) {// if there is no port, a random port will be given automatically
  if (err) {
    console.log(err);
  }
});

In order to facilitate our access, the project usesminihostIt is convenient and fast to start. It is worth mentioning that the use ofh -- npm startWhen the command starts, the name of the project folder is accessed as a link, for example, the project namemyproject, then you can accessmyproject.t.t

Redux

For complex spa, state management is very important. State may include: server response data, local cache of response data, locally created data (such as form data) and some UI status information (such as route, selected tab, whether to display drop-down list, page number control, etc.). If the state changes unpredictably, it will be difficult to debug (the state is not easy to reproduce, and it is difficult to reproduce some bugs) and expand (for example, optimizing and updating rendering, server-side rendering, obtaining data during route switching, etc.).

State is a single object, so that Redux only needs to maintain a state tree. It is easy for the server to initialize the state and easy for the server to render. State can only be updated through dispatch (action), and the update logic is executed by reducer.

After using Redux, the state becomes easy to maintain, and the data flow is very clear, which is easy to solve the bugs encountered.

We can briefly understand Redux by looking at the following figure:

The structure we can see in the project is:

├─store
├─actions
├─reducers
├─constants
├─helpers
├─components
├─app.js
├─favicon.ico
├─index.html
├─index.js
└─routes.js

Finally, our store is:

import {createStore, applyMiddleware, combineReducers, compose} from 'redux';
import thunk from 'redux-thunk';
import {reduxReactRouter} from 'redux-router';
import createHistory from 'history/lib/createHashHistory';

import routes from '../routes';
import * as reducers from '../reducers';

let middlewares = [thunk];

If (process. Env. Node_env = = = 'development') {// you can see the state log in the development environment
  const logger = require('redux-logger');
  middlewares = [...middlewares, logger];
}

Const finalcreatestore = compose (// combine multiple functions
  applyMiddleware(...middlewares),
  reduxReactRouter({routes, createHistory}),
)(createStore); // Create a store to manage all States

export default function configureStore(initialState) {
  const reducer = combineReducers(reducers);  // Combine an object with multiple different reducer functions as value into a final reducer function
  const store = finalCreateStore(reducer, initialState);

  If (process. Env. Node_env = = = 'development' & & module. Hot) {// hot loading in development environment
    module.hot.accept('../reducers', () => {
      const nextReducers = require('../reducers');
      const nextReducer = combineReducers(nextReducers);
      store.replaceReducer(nextReducer);
    });
  }

  return store;
}

To get the state, you need to call theconnectFunction, you can define the state you need to get. (this is used to distinguish between display and container components)

...
@connect(
  state => ({
    data: state.data
  })
)
export default class ComponentOne extends Component {
  ...
}

be carefulconnectThe definition of component must be followed closely, or an error will be reported.

Router

Add a routing system for the project and use the react router to manage the routing. When developing a project, it is recommended to use routing to jump to the page, and add the router while creating the store, and then update the view according to the change of routing.

We can look at the source code of Routing:

import React from 'react';
import Route from 'react-router/lib/Route'; //import {Route} from 'react-router';
import Base from 'components/base/Base';
import Home from 'components/home/Home';

export default (
  <Route component={Base}>
    <Route path="/" component={Home} />
    <Route path="/home" component={Home} />
  </Route>
);

pathIt’s a jump path,componentIs a component that matches the path.

Ant Design

A UI design language produced by ant financial services technology department is also the UI component library used in the project.

characteristic:

  • Designed as ant design refines and serves the interactive language and visual style of enterprise level middle and back office products

  • React ComponentHigh quality UI library carefully encapsulated on

  • Workflow based on NPM + webpack + Babel, supporting es2015

Reason for selection:

  • Good technical support

  • Simple style

  • It basically covers common components

Simple component

As a basic component of react rendering, components are usually divided into two categories,Container typeandDisplay type。 Compared toContainer typeDisplay typeYesContainer typePass props to get data, andContainer typeIt can be directly obtained from the store, processed and passed to lower level components.

In practical application, it will be found that defining a container component is responsible for processing data and then distributing it to lower level display components. When the data needs to be updated, the change of container components will cause the change of lower level display components, which will cause some trouble in our business (updates have also occurred on some components that do not need to be updated). Therefore, we choose to use it in the components that need to obtain dataconnect, it will be much more convenient (I feel a little against the rules).

In the project, we will define components as follows:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import Presentational from 'components/common/Presentational';

@connect(
  state => ({
    data: state.data
  })
)
export default class Container extends Component {

  render() {
    const {data} = this.props;

    return (
      <Presentational data={data} />
    )
  }
}

The above is a component that can get data from the store and nest another component to pass data to it.

import React, {Component, PropTypes} from 'react';

export default class Presentational extends Component {

  static propTypes = {
    data: PropTypes.string,
  }

  render() {
    const {data} = this.props;

    return (
      <div>
        {data}
      </div>
    )
  }
}

Get the data passed from the previous component and display it.

summary

This is a popular science article (ha ha ~ embarrassing), which does not deeply analyze the specific contents of various technologies. I hope it can help novices who have just started react. The source code of the practice project can be found inreact-start-kitSee, you can download this project for your own exploration and development. It is still trying to explore. There are improper wording or omissions in the text. Comments and suggestions are welcome.

reference resources

React official website
Babel official website
Introduction to Redux
Redux Chinese document
Ant Design official website
Introduction to react example tutorial
React router Chinese document
Webpack fool’s Guide (I)
Detailed explanation of CSS modules and practice in react
Reactjs introductory tutorial (essence version)
In simple terms (II): react development artifact webpack