Introduction to React: From Web pack to react-router and state management

Keywords: Javascript React npm Webpack JSON

I. What is React

What is React? React's official website is introduced as follows:
React - JavaScript library for building user interfaces.
It seems very concise. React just wants to provide a tool for building user interfaces, that is, it only cares about the UI level, not the data level, and the data level is left to a dedicated person (react-redux). So some people would say that React is a UI framework.
React believes that rendering logic is intrinsically coupled with other UI logic, such as the need to bind to handle events in the UI, notify the UI when state changes at certain times, and display ready data in the UI. So React provides jsx syntax, which can also be understood as letting you write a lot in ul components. jsx is ultimately invoked by converting components into React.createElement() functions through babel. The fun of component development needs to be realized slowly. Now that it's an introduction, let's briefly introduce react by building projects - small examples - introducing routing / state management. The complex concepts are not mentioned here.

const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);

II. Project Construction

As mentioned above, react component development requires babel compilation, browsers can not be directly parsed, so react projects generally need to do some simple configuration. Of course, there are many well-equipped scaffolding can be used, such as the official scaffolding creat-react-app or the dva framework of ant golden clothes, which are very convenient to use. But I think we can understand react better by simply building a project. The next step is to build a usable project through web pack, but the specific optimization is not considered here.

1. Open the terminal and create the project

mkdir react-demo && cd react-demo //Create folders and enter them

2. Initialization Construction

npm init //Use for downloading npm packages and node configuration later
         //Enter key all the way! An extra package.json file came out of the project

3. Create project entry

Create a new app.js file, introduce react and react-dom, and create a new index.html containing <div id='app'> </div>.

    import React from 'react'; // Terminal performs npm i react download react
    import ReactDom from 'react-dom' // Terminal execution npm i react-dom download react-dom
    
    function App(){ //Creating react components in a functional way
        return <div>welcom,react-app</div>
    }
    
    ReactDom.render( //Mount component App rendering to the root node app of the page
        <App />,
        document.getElementById('app')//So you need to create a new html file to provide app nodes for component mounting
    )

3. Web pack configuration

After creating the entry file app.js, we need to compile the jsx grammar file through babel. So we first introduce webpack, and create a new JS file webpack.config.js to do the relevant configuration as follows:

npm i webpack webpack-cli --save //Installing webpack and cli dependencies

webpack.config.js Document content:

const path = require("path");
const {CleanWebpackPlugin} = require('clean-webpack-plugin');//Installation through npm
const HtmlWebpackPlugin = require('html-webpack-plugin'); //Installation through npm
module.exports = {
    entry:{
        app:'./app.js'
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: '[name].bundel.[hash].js'
    },
    module:{
        rules: [{
            test: /\.js$/,
            exclude: /(node_modules|bower_components)/,
            use:[{
                loader: 'babel-loader',
                options: {
                  presets: [
                      '@babel/preset-env',//Introducing babel
                      '@babel/preset-react' //Introducing babel-react 
                    ]
                }
            }]
        }]
    },
    plugins: [
        new CleanWebpackPlugin(),//Clear the dist folder
        new HtmlWebpackPlugin({
            template: './index.html'
        }),//Add html template plug-in
    ]
}


//Installation Dependency:
npm install babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env @babel/preset-react --save

npm i html-webpack-plugin clean-webpack-plugin --save

4. Configure npm/script startup

Open the package.json file and add a line of script code as follows:

At this point, our code structure is as follows:

When we execute the npm run build command on the terminal, we can see more dist folders packaged and js files packaged as follows:

Open the index.html file under dist in the browser, OK, the first line of react code flashes!

4. Modify npm/script startup
Although the above code shows up, but can't change the code every time you execute a package, too troublesome? Let's build a server. It's very comfortable to use local hot update (hmr) in collocation. Three areas need to be revised:

1.stay webpack.config.js Add the following code to the file:
devServer: {//Open a local service
        port: 9000,//port
        host:"0.0.0.0",//After configuration, it can be accessed through local ip, which is convenient for debugging on mobile phone.
        hot:true,//
}
2.Modify the entry file app.js: 
import React from 'react';
import ReactDOM from 'react-dom'
import {hot} from 'react-hot-loader/root'//Add dependencies, download through npm

function AppCont(){
    return <div>welcom,react-app hot</div>
}
const App = hot(() =>{//The outer layer of the root component is wrapped by higher-order components
    return <AppCont />
})

ReactDOM.render(
    <App />,
    document.getElementById('app')
)
3.modify package.json Document: Add a new script command dev

"dev": "webpack-dev-server --mode=development --config  webpack.config.js"

Execute npm run dev command, open http://localhost 9000/, you can see that the content of the page appears. After adding hot after the text, you find that the content of the page has been updated, but not refreshed! ok to this point, a simple project has been built and can be developed.

3. Some Concepts of React

Here we describe some of the react concepts with a simple example. Input box input number, click add + data after change and sum.

import React from 'react';

function Item (props){
    const {count,onChange,onAdd} = props;
    return <div>
        <input value={count} onChange={onChange} />
        <span onClick={onAdd}>add+</span>
    </div>
}

class Add extends React.Component{
    constructor(){
        super();
        this.state = {
            addList : [0,0,0,0]
        }
        this.onChange = this.onChange.bind(this)
        this.onAdd = this.onAdd.bind(this)
    }
    onChange(e,index){
        this.state.addList.splice(index,1,e.target.value)
        this.setState({
            addList:this.state.addList
        })
    }
    onAdd(e){
        this.state.addList.splice(e,1,Number(this.state.addList[e]) + 1 )
        this.setState({
            addList:this.state.addList
        })
    }
    render (){
        const { addList } = this.state;
        return <div>
            {
                addList.map((item,index)=>{
                   return <Item key={index} count={item} onChange={(e)=>{this.onChange(e,index)}} onAdd={()=>{this.onAdd(index)}}  />
                })

            }
            <div>{addList[0]*1 + addList[1]*1 + addList[2]*1 + addList[3]*1}</div>
        </div>
    }
}

export default Add;

Sparrows are small enough to get started!

1. Three ways to create react components

1.React.createClass
Commonly used are class inheritance and stateless functions, and a React.createClass that is too cumbersome and leads to unnecessary performance overhead is basically abandoned.
2. Stateless components
Written directly through function declaration, it is generally used as a pure display component. There is no state (which can be used by hooks) in it. It will not be instantiated, and it does not need to allocate extra memory, so the performance will be improved to a certain extent. But there is no internal use of this and no life cycle.
3.React.Component
React currently favors the way to create stateful components. Internally, this and lifecycle can be used. You can use state.
The component created by React.Component, whose member functions do not automatically bind this, needs to be manually bound, otherwise this cannot get the current component instance object. There are three ways to bind: you can complete the binding in the constructor (recommended by the constructor), you can use method.bind(this) to complete the binding when calling, and you can use arrow function to bind.

2. Parametric transfer

Generally, the parent passes parameters to the child through props.
The child passes to the parent through the function passed by the parent component.
Cross-component delivery will be followed by a reference to using redux to pass as you want.

3. Controlled Components/Uncontrolled Components

In addition to receiving state control, form elements are also controlled by user input. There are two sources that make the content unpredictable. React uses state as the "only data source". The React component that renders the form also controls what happens to the form during user input. Form input elements controlled by React in this way are called "controlled components".
You can see that the onChange function is provided to the controlled component to ensure the unity of state data.

3. Introducing redux

As you can see above, it's also convenient to pass parameters between parent and child components, but what if you want to use the sum data outside of the Add component (i.e., cross-component transfer)?
Of course, you can use methods such as adding intermediate components and context. Here we talk about the redux state management commonly used in large-scale projects. The principle of redux itself is also simple.
1. Provide createStore to create store library, store all data together, one-way data flow.
2. Data is read-only. Data can only be modified by dispatch method. action objects (which must contain type attributes) can be modified in pure function reduce. Each time, a new data is copied, and the original data source will not be modified, thus ensuring the traceability of data sources.

modify app.js
import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux'; //After adding redux dependencies, the method of creating store s, createStore, is introduced.
import {Provider} from 'react-redux';//Adding react-redux dependencies and introducing modification components
import reduce from './model/reduce';//The first parameter of the createStore method is reduce
import {hot} from 'react-hot-loader/root';
import AddItem from './component/addItem';


const store = createStore(reduce)

function AppCont(){
    return <Provider store={store}><AddItem /></Provider>//Enwrap higher-order components outside the root component
}
const App = hot(() =>{
    return <AppCont />
})

ReactDOM.render(
    <App />,
    document.getElementById('app')
)

Create a new reduce file to process the reduce function. Since the latter projects are huge, reduce letters must be too bulky to write together. Reux provides a method of splitting, which can be split through business, and finally merged through combineReducers.

import {combineReducers} from 'redux';
const initState = {
    addList:[0,0,0,0]
}

function addSum(state=initState,action){
    switch (action.type){
        case 'add' : 
            return {
                ...state,
                addList:[...action.payload]
            }
        default : return {...state}
    }
    
}
export default combineReducers({
    addSum
})

The addItem file needs to be modified to store the data originally written in the state. The modification is the same as adding the Sum component: connecting the component to the store through the connect function.

import React from 'react';
import {connect} from 'react-redux';
function Sum(props){
    const {addList} = props
    return <div>{
        Number(addList[0]) + Number(addList[1]) + Number(addList[2]) + Number(addList[3])
    
    }</div>
}
export default connect(data=>data.addSum)(Sum);

IV. Introducing react-router

In the react single page mode, routing is very important. The react eliminates the router individually and forms a separate component, which is more convenient to use and reduces the coupling degree of the code.
HashRouter and BrowserRouter are two kinds of root routing modes. The important difference is that HashRouter is accessed through hash path. It can be accessed by browser directly inputting address. BrowserRouter accesses through history api of h5. When inputting address, it will be like a server inquiry. Because it is a single page, there is no history, it can not be inquired. No. By configuring history ApiFallback: true through our devserver using webpack, we can access it, as well as server rendering.

    npm i react-router-dom --save
 <Router>
    <Route path="/" component={AddItem}></Route>
    <Link to="/tab1/1">tab1</Link>
    <Link to="/tab2/2">tab2</Link>
    <Link to="/tab3/3">tab3</Link>
    <Route path="/tab1/:num" component={PageItem}></Route>
    <Route path="/tab2/:num" component={PageItem}></Route>
    <Route path="/tab3/:num" component={PageItem}></Route>
 </Router>

OK, now that a simple react development framework has been built, you should get started here.


If there is any mistake, please correct it.


Posted by jayloo on Tue, 27 Aug 2019 06:04:39 -0700