Multiplayer blog development project - front end

Posted by Chrisj on Tue, 29 Oct 2019 05:10:21 +0100

I. development environment settings

1 installation package environment

The package is as follows
Links: https://pan.baidu.com/s/1C-ZY9rWU-8ZugE4EwVveWw
Extraction code: 744p

Related react introduction links are as follows
https://blog.51cto.com/11233559/2443713

Unzip and modify the directory to blog without special instructions. js files are placed in src directory.

2 modify relevant information

1 modify project information

2. Modify the reverse generation and local listening ports

The back-end service ip address of this environment is 192.168.1.200, and the back-end python listening port is 80.

3 install software

npm  i

Launch and view

npm  start  

Function development of second login module

1 front end routing configuration

This time, use react router to configure routes
Basic example

https://reacttraining.com/react-router/web/example/basic

Official documents

https://reacttraining.com/react-router/web/guides/quick-start

According to the official example, modify src/index.js as follows

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
const  Home =()  => {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
const  About=()  => {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}
class Root  extends  React.Component  {
  render() {
    return  (
         <Router> 
        <div>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </div>
    </Router>
     )
  }  
}
ReactDom.render(<Root />,document.getElementById('root'));

The results are as follows

Route is responsible for static routing
Path is a matching path, no path always matches.
Component is the target component.
exact: Boolean value. true requires the path to match exactly.
Strict: Boolean value, strict matching is required when true, but the url string can be its own string.

When the address changes, the Router component will match the path, and then use the matching component to render.

2. Log in to the front view layer

1 global CSS configuration

Add CSS directory and create global CSS file login.css

body {
    background: #456;
    font-family: SimSun;
    font-size: 14px;
}
.login-page{
    width: 360px;
    padding: 8% 0 0;
    margin: auto;
}

.form {
    font-family: "Microsoft YaHei",SimSun;
    position:  relative;
    z-index:1;
    background: #ffffff;
    max-width: 360px;
    margin: 0 auto  100px;
    padding: 45px;
    text-align: center;
    box-shadow: 0 0  20px 0  rgba(0,0,0,0.2), 0 5px 5px 0  rgba(0,0,0,0.24);
}

.form  input{
    outline: 0;
    background: #f2f2f2;
    width: 100%;
    border: 0;
    margin: 0 0 15px;
    padding: 15px;
    box-sizing: border-box;
    font-size: 14px;
}

.form  button{
    text-transform: uppercase;
    outline: 0;
    background: #4cAf50;
    width: 100%;
    border: 0;
    padding: 15px;
    color: #ffffff;
    font-size: 14px;
    cursor: pointer;
}

.form button:hover,.from button.active,.form button.focus {
    background: #43a047;
}
.from .message{
    margin: 15px 0 0;
    color: #bb33bb;
    font-size: 12px;
}

.form .message a{
    color: #4caf50;
    text-decoration: none;
}

as follows

2. Implementation of view layer of login module

Building react component under component directory

Login template
https://codepen.io/colorlib/pen/rxddKy?q=login&limit=all&type=type-pens

Add the component directory under src.

The HTML login template is as follows

<div class="login-page">
  <div class="form">
    <form class="register-form">
      <input type="text" placeholder="name"/>
      <input type="password" placeholder="password"/>
      <input type="text" placeholder="email address"/>
      <button>create</button>
      <p class="message">Already registered? <a href="#">Sign In</a></p>
    </form>
    <form class="login-form">
      <input type="text" placeholder="username"/>
      <input type="password" placeholder="password"/>
      <button>login</button>
      <p class="message">Not registered? <a href="#">Create an account</a></p>
    </form>
  </div>
</div>

Use this HTML template to build components

Be careful:

When moving to the React component, change the class attribute to ClassName
All labels, must be closed

login.js create

Create login.js login component in component directory
Use the login section of the HTML template above to move to the render function.
as follows

import React  from  'react';
import  {Link}  from  'react-router-dom';
export default  class Login  extends React.Component{
    render(){
        return  (
            <div className="login-page">
                <div className="form">
                    <form className="register-form">
                    <input type="text" placeholder="mailbox"/>
                    <input type="password" placeholder="Password"/>
                    <button>Sign in</button>  {/*Trigger button*/}
                    <p className="message">Not yet registered <Link  to="/reg">Please register</Link></p>
                    </form>
                </div>
            </div>
        )
    }
} 

Add the route in index.js as follows

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Login  from  './component/login'  //Introducing objects
const  Home =()  => {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
const  About=()  => {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}
class Root  extends  React.Component  {
  render() {
    return  (
         <Router> 
        <div>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route  path="/login" component={Login} />  {/*This is mainly to jump to the login object.*/}
      </div>
    </Router>
     )
  }  
}
ReactDom.render(<Root />,document.getElementById('root'));

give the result as follows

Import style sheets as follows

import React  from  'react';
import  '../css/login.css'
import  {Link}  from  'react-router-dom';
export default  class Login  extends React.Component{
    render(){
        return  (
            <div className="login-page">
                <div className="form">
                    <form className="register-form">
                    <input type="text" placeholder="mailbox"/>
                    <input type="password" placeholder="Password"/>
                    <button  onClick={event =>console.log(event)}>Sign in</button>  {/*Trigger button*/}
                    <p className="message">Not yet registered <Link  to="/reg">Please register</Link></p>
                    </form>
                </div>
            </div>
        )
    }
} 

give the result as follows

The default data passed in the page is from data

3 get trigger data

Define handlerClick function in src/component/login.js to get the data generated by trigger event
Each filling in above will lead to page refresh, rather than refresh after clicking submit. To prevent page refresh, in fact, to prevent submission, you can use event.preventDefault() to prevent automatic submission of the page.

How to get the mailbox and password

event.target.from returns the form where the button is located, which can be regarded as an array.

fm[0].value and fm[1].value are the values of the text box

How to use the UserServie instance in the login component:
1 initialize directly in the Login constructor
2 in props

The relevant codes are as follows

import React  from  'react';
import  '../css/login.css'
import  {Link}  from  'react-router-dom';
export default  class Login  extends React.Component{
    handlerClick(event){
        event.preventDefault(); //Its default is to write a data submission once, which is used to prevent its default submission 
        console.log('mailbox',event.target.form[0].value)  // This is used to obtain the login information of related users.
        console.log('Password',event.target.form[1].value)

    }
    render(){
        return  (
            <div className="login-page">
                <div className="form">
                    <form className="register-form">
                    <input type="text" placeholder="mailbox"/>
                    <input type="password" placeholder="Password"/>
                    <button  onClick={this.handlerClick.bind(this)}>Sign in</button>  {/*Trigger button*/}
                    <p className="message">Not yet registered <Link  to="/reg">Please register</Link></p>
                    </form>
                </div>
            </div>
        )
    }
} 

give the result as follows

The data submitted by the form can be obtained through the above event.target.form[1].value

3. view implementation of registration interface

1 basic page implementation

Create reg.js in component to register function

import React  from  'react';
import  '../css/login.css'
import  {Link}  from  'react-router-dom';
import  UserService   from  '../service/user'
const  service= new  UserService();
export  default  class  Reg  extends React.Component{
    render(){
        return  <_Reg    server={service} />; {/*Pass the service here. In the later stage, you can use props.service.xxx to complete the data injection operation.*/}
    }
}

class _Reg   extends  React.Component  {
        handleClick(event) {
            event.preventDefault();  //Handle page refresh and block default behavior
            let fm=event.target.form;
            console.log(fm[0].value,fm[1].value,fm[2].value,fm[3].value)  //Get registration information
        }
        render() {
            console.log('++++++++++++++++++++++++')
          return  (
            <div className="login-page">
                <div  className="form">
                    <form  className="register-form">
                        <input type="text" placeholder="Full name" />
                        <input type="text" placeholder="mailbox" />
                        <input type="password" placeholder="Password" />
                        <input type="password" placeholder="Confirm password" />
                        <button onClick={this.handleClick.bind(this)}>register</button>
                        <p className="message">If registered <Link  to="login">Please login.</Link></p>  {/*Here for jump*/}
                    </form>
                </div>
            </div>       
           )
        }  
      }

Add routing

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Login  from  './component/login';
import Reg  from  './component/reg';
const  Home =()  => {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
const  About=()  => {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}
class Root  extends  React.Component  {
  render() {
    return  (
         <Router> 
        <div>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route  path="/login" component={Login} />
        <Route  path="/reg" component={Reg} />
      </div>
    </Router>
     )
  }  
}
ReactDom.render(<Root />,document.getElementById('root'));

give the result as follows

The above contents filled in the form can be obtained directly in fm[x].value

4navigation bar components

Add navigation bar in index.js to facilitate the switching between pages

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Login  from  './component/login';
import Reg  from  './component/reg';
const  Home =()  => {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
const  About=()  => {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}
class Root  extends  React.Component  {
  render() {
    return  (
         <Router> 
        <div>
        <ul> {/*Navigation bar related*/}
          <li><Link to="/">homepage</Link></li>
          <li><Link to="/about">about</Link></li>
          <li><Link to="/reg">register</Link></li>
          <li><Link to="/login">Sign in</Link></li>
        </ul>

        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route  path="/login" component={Login} />
        <Route  path="/reg" component={Reg} />
      </div>
    </Router>
     )
  }  
}
ReactDom.render(<Root />,document.getElementById('root'));

give the result as follows

5 synchronous and asynchronous

1 synchronization

Simulated sleep

d1=new Date();
for  (var d=new Date();(new Date())-d <1000;);// This is equivalent to sleep processing 
console.log('------------')
d2=new Date();
console.log(d2-d1)

give the result as follows

Modification of login code

component/login.js

import React  from  'react';
import  '../css/login.css'
import  {Link}  from  'react-router-dom';
import  UserService  from  '../service/user'
export default  class Login  extends React.Component{
    constructor(prpos){
        super(prpos);
        this.service=new  UserService;
        this.state={'ret':-1};
    }

    handlerClick(event){
        event.preventDefault(); //Its default is to write a data submission once, which is used to prevent its default submission 
        // console.log('mailbox ', event.target.form[0].value) / / used here to obtain the login information of related users.
        // console.log('password ', event.target.form[1].value)
        console.log('this----------',this) //this here refers to the Login instance, which can be passed in to modify the ret value to trigger page refresh.
        let  fm=event.target.form
        this.service.login(fm[0].value,fm[1].value,this);  //This is used to transfer the current login and related form data to the backend service layer.
        console.log(this.state.ret)

    }
    render(){
        if  (this.state.ret  != -1 ){  // If there is any change here, its status will be refreshed.
            console.log('ret',this.state.ret)  //Print refresh results
        }

        return  (
            <div className="login-page">
                <div className="form">
                    <form className="register-form">
                    <input type="text" placeholder="mailbox" defaultValue="12345@123"/>
                    <input type="password" placeholder="Password"  defaultValue="demo"/>
                    <button  onClick={this.handlerClick.bind(this)}>Sign in</button>  {/*Trigger button*/}
                    <p className="message">Not yet registered <Link  to="/reg">Please register</Link></p>
                    </form>
                </div>
            </div>
        )
    }
} 

The relevant codes are as follows

import  axios  from 'axios'

export   default  class  UserSerive{
    login(email,password,obj){
        for  (var d=new Date();(new Date())-d <10000;);// This is equivalent to sleep processing 
        console.log('12433645645765')
        console.log(email,password,obj)
    }
}

As a result, the browser directly pauses when requesting data, and other related pages cannot be refreshed or clicked.

2 asynchronous

1 setTimeout

export   default  class  UserSerive{
    login(email,password,obj){
        setTimeout(()=> {console.log('timeout---------');obj.setState({'ret':parseInt(Math.random()*100)})},
            10*1000
        )
        console.log(email,password,'Userservice')
    }
}

The result here is that its email,password and 'Userservice' are printed immediately, but its timeout and subsequent printing lag by 10s. However, in the process of 10s, its page can be clicked and its current business execution is not blocked.

obj.setState({'ret':parseInt(Math.random()*100)}) used here to generate random integers

2 Promise

The official website code is as follows

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
class Root  {
    login(){
    new Promise((resolve,reject) => {
        setTimeout(
            ()=> {
                console.log('timeout......')
                // reject('ok');
                resolve('not ok')
                },5*1000
            )
        }
    ).then( value => {
        console.log('then++++++++++++++++++++++++++')
        console.log('then-------------------','UserService')

    }).catch(value =>  {
        console.log('then-------------------------')
    })
    console.log('12423423523534564')
}
    }
login=new Root();

login.login()

give the result as follows

export   default  class  UserSerive{
    login(email,password,obj){
        new  Promise((resolve,reject) => setTimeout(
            () =>  {
                console.log('timeout ........');
                resolve('ok')  //Call here to execute the code in then
            },5*1000)).then(value =>  
                obj.setState({'ret':parseInt(Math.random()*100)}),
                console.log('then-------------')
                )
            console.log(email,password,'Userobject')
    }
}

The result here is to print email,password and 'userobject' for 5 seconds before relevant timeout output and corresponding rendering operation. Because the page is changed, DOM rendering will not be performed.

The test code is as follows

class Root  {
    login(){
    new Promise((resolve,reject) => {
        setTimeout(
            ()=> {
                console.log('timeout......')
                reject('ok');
                // resolve('not ok')
                },5*1000
            )
        }
    ).then( value => {
        console.log('then++++++++++++++++++++++++++')
        console.log('then-------------------','UserService')

    }).catch(value =>  {
        console.log('then-------------------------')
    })
    console.log('12423423523534564')
}
    }
login=new Root();

login.login()

The results are as follows: the result printed here is 124234523523534564, and then the content in then is output after timeout. This indicates that the above timeout does not block the operation of the program itself, and this is the asynchronous call mode. It does not affect the next data processing of the current request

3 axios

axios is a promise based HTTP asynchronous library, which can be used in browsers or nodejs.

Use axios to initiate asynchronous call to complete data submission of post and get methods. Please refer to the official website example.

http://www.axios-js.com/zh-cn/docs/

install

npm  i  axios 

Import

import  axios  from 'axios'

The basic examples are as follows

Basic GET implementation

axios.get('/user', {   //The user here is the url of the api, and the absolute path is specified.
    params: {  //Here is the value passed
      ID: 12345
    }
  })
  .then(function (response) {  //Here is the return value of the request success
    console.log(response);
  })
  .catch(function (error) { //Here is the return value of the failure
    console.log(error);
  });  

Basic POST implementation

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

6 implementation of login interface

The specific code is as follows

import { comparer } from "mobx";
import  axios  from  'axios'
// import { object } from "prop-types";
// import { resolve } from "dns";
//Handling of user logic
export default  class  UserService{
    login(email,password,obj) {
        axios.post('/api/user/login', {
            'email':  email,
            'password': password
          })
          .then(function (response) {   //Successful operation
            console.log(response,'===================');
            console.log(response.data)
            console.log(response.status);
            obj.setState({'ret':parseInt(Math.random()*100)})  //When it returns to success, change the state and enter the rendering dom.
          })
          .catch(function (error) { //Failed action
            console.log(error);
          });
        console.log(email,password,'UserService')//How to transmit, what to transmit, what to return and how to return
        }
}

The front-end page is implemented as follows

import React  from  'react';
import  '../css/login.css'
import  {Link,Redirect}  from  'react-router-dom';
import  UserService  from  '../service/user'
export default  class Login  extends React.Component{
    constructor(prpos){
        super(prpos);
        this.service=new  UserService;
        this.state={'ret':-1};
    }

    handlerClick(event){
        event.preventDefault(); //Its default is to write a data submission once, which is used to prevent its default submission 
        // console.log('mailbox ', event.target.form[0].value) / / used here to obtain the login information of related users.
        // console.log('password ', event.target.form[1].value)
        console.log('this----------',this) //this here refers to the Login instance, which can be passed in to modify the ret value to trigger page refresh.
        let  fm=event.target.form
        this.service.login(fm[0].value,fm[1].value,this);

    }
    render(){
        if  (this.state.ret  !=-1 )  //This is used to judge whether to jump to about page directly when it is not - 1.
            return  <Redirect  to='/about' />
        return  (
            <div className="login-page">
                <div className="form">
                    <form className="register-form">
                    <input type="text" placeholder="mailbox" defaultValue="12345@123"/>
                    <input type="password" placeholder="Password"  defaultValue="demo"/>
                    <button  onClick={this.handlerClick.bind(this)}>Sign in</button>  {/*Trigger button*/}
                    <p className="message">Not yet registered <Link  to="/reg">Please register</Link></p>
                    </form>
                </div>
            </div>
        )
    }
} 

The defaultValue in the above is handled for easy login.

The data obtained are as follows

7 localStorage and expiration implementation

Use the store to write to the local storage of the client and use its own plug-in to handle the expiration mechanism

Related official website

https://github.com/marcuswestin/store.js/

Expired plug-in

The relevant expiration codes are as follows

https://github.com/marcuswestin/store.js/blob/master/plugins/expire_test.js

Add out of date plug-ins and configurations

store.addPlugin(require('store/plugins/expire'))

Configuration overdue

store.set('token',response.data.token,(new  Date()).getTime()+(8*3600*1000));

8 mobx status management

1 demand

onClick of a component triggers the event response function, which will call the background service, but the background service is quite time-consuming. When the processing is completed, the rendering operation of the component needs to be caused.
To render a component, you need to change the props or state of the component

1 synchronous call

Temporarily modify index.js as follows

import React from 'react';
import ReactDom from 'react-dom';

class  Service{
  handler(e){
      console.log('pending..............')
      for (let d=new Date();new Date() -d < 1000*e;) //This is the synchronous blocking model
      console.log('output')
      return  parseInt(Math.random()*100)

  }
}

class  Root  extends  React.Component{
  state={'ret':-100}
  handlerClink(){
      this.setState({'ret':this.props.service.handler(10)})
  }
  render(){
    return  (<div>
          <button   onClick={this.handlerClink.bind(this)}> Click trigger button </button>
          <span  style={{color:'red'}}>  {new Date().getTime()}  {this.state.ret} </span>
    </div>)
    }
  }
ReactDom.render(<Root  service={ new Service() }/>,document.getElementById('root'));

The result is that the page is refreshed after 10 seconds, but it cannot click other pages during this period.

2 asynchronous call

Idea 1: use setTimeout
There are two problems in using setTimeout

1 cannot pass parameters to the internal function to be executed, such as Root instance
2. The return value of delayed function is obtained repeatedly, so Root cannot be notified.

Idea 2: promise asynchronous execution
promise is executed asynchronously. If the execution is successful, call the callback.

 import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
class  Service{
  handler(obj){
    new Promise((resolve,reject)=>{
      setTimeout(()=>  //Success here, return to this value
        resolve('ok')
      ,5000)
      }).then(value => { 
        obj.setState({'ret':parseInt(Math.random()*1000)})
    })

  }
}

class  Root  extends  React.Component{
  state={'ret':-100}
  handlerClink(){ 
    console.log('trigger')
    this.props.service.handler(this)
  }
  render(){
    return  (<div>
          <button   onClick={this.handlerClink.bind(this)}> Click trigger button </button>
          <span  style={{color:'red'}}>  {new Date().getTime()}  {this.state.ret} </span>
    </div>)
    }
  }
ReactDom.render(<Root  service={ new Service() }/>,document.getElementById('root'));

give the result as follows

In the process of the event being called, the above method does not affect the click of the page and does not block the normal processing of the page.

3 Mobx implementation

observable decorator: set the observed

Observer decorator: set observer

1 mobx + Promise implementation code

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Login  from  './component/login';
import Reg  from  './component/reg';
import   {observable}   from  'mobx'
import  {observer}  from  'mobx-react'
class Service{
    @observable ret=-100;
    handler(){    
      new Promise((resolve,reject)  => {
          setTimeout(()=>resolve('ok'),5000)
    }).then((value)=> {
      this.ret=parseInt(Math.random()*100)
    })
  }
}

@observer
class Root  extends  React.Component{
  handlerClink(){
      this.props.service.handler();
  }
  render(){
    return  <div>
        <button  onClick={this.handlerClink.bind(this)}> Click trigger </button>
        <span  style={{color:'red'}} >  {new Date().getTime()}  {this.props.service.ret} </span>
    </div>
  }
}

ReactDom.render(<Root service={new Service() } />,document.getElementById('root'));

The basic conclusion is the same as the above, and its clicking will not cause page problems, thus realizing the purpose of asynchronous request.

2 mobx + axis code implementation

login is triggered to the about page as follows
The code in src/service/user.js is modified as follows

import  axios  from  'axios'
import  {observable}  from  'mobx'
import  store  from  'store'
store.addPlugin(require('store/plugins/expire'))  //Load out of date plug-ins, return an object here
//Handling of user logic
export default  class  UserService{
  @observable loggin=0;  //The observed object has been observed. Once the value changes, the observer will know.
    login(email,password) {
        axios.post('/api/user/login', {
            'email':  email,
            'password': password
          })
          .then( (response) => {   //The problem of this is solved by arrow function.
            console.log(response,'===================');
            console.log(response.data)
            console.log(response.status);
            //obj.setState({ret:1000}) / / state trigger causes change
            store.set('token',response.data.token,(new Date()).getTime()+(8*3600*1000));//getTime gets time, but it's milliseconds
            this.loggin = Math.random() * 100;  //Modified value
            console.log(this.loggin)

          })
          .catch( (error) => { //Failed action
            console.log(error);
          });
        //for (var d=new Date();(new Date())-d < 10 * 1000;); / / here is synchronization
        console.log(email,password,'UserService')//How to transmit, what to transmit, what to return and how to return
        }
}

The result of src/component/login.js is as follows

import React  from  'react';
import  '../css/login.css'
import  {Link,Redirect}  from  'react-router-dom';
import  UserService  from  '../service/user'
import  {observer}   from  'mobx-react'
let service  = new  UserService()
export    default  class Login  extends React.Component  {
    render(){
        return  < _Login service={service}/>
    }
}  

@observer
class _Login  extends React.Component{
    handlerClick(event){
        event.preventDefault(); //Its default is to write a data submission once, which is used to prevent its default submission 
        console.log('this----------',this) //this here refers to the Login instance, which can be passed in to modify the ret value to trigger page refresh.
        let  fm=event.target.form
        this.props.service.login(fm[0].value,fm[1].value,this);

    }
    render(){
        if  ( this.props.service.loggin)
            return  <Redirect  to='/about' />
        return  (
            <div className="login-page">
                <div className="form">
                    <form className="register-form">
                    <input type="text" placeholder="mailbox" defaultValue="12345@123"/>
                    <input type="password" placeholder="Password"  defaultValue="demo"/>
                    <button  onClick={this.handlerClick.bind(this)}>Sign in</button>  {/*Trigger button*/}
                    <p className="message">Not yet registered <Link  to="/reg">Please register</Link></p>
                    </form>
                </div>
            </div>
        )
    }
} 

The overall results are as follows

9. Perfect registration interface

1 Parameter deconstruction

let a=1,b=2,c=3
var obj={a,b,c}
console.log(obj)

give the result as follows

2. Perfect registration interface

The configuration in src/service/user.js is as follows

import  axios  from  'axios'
import  {observable}  from  'mobx'
import  store  from  'store'
store.addPlugin(require('store/plugins/expire'))  //Load out of date plug-ins, return an object here
//Handling of user logic
export default  class  UserService{
    @observable loggin=0;  //The observed object has been observed. Once the value changes, the observer will know.
    @observable  regin=0;  //Define the observed object of login
    login(email,password) {
        axios.post('/api/user/login', {
            'email':  email,
            'password': password
          })
          .then( (response) => {   //The problem of this is solved by arrow function.
            console.log(response,'===================');
            console.log(response.data)
            console.log(response.status);
            //obj.setState({ret:1000}) / / state trigger causes change
            store.set('token',response.data.token,(new Date()).getTime()+(8*3600*1000));//getTime gets time, but it's milliseconds
            this.loggin = Math.random() * 100;  //Modified value
            console.log(this.loggin)

          })
          .catch( (error) => { //Failed action
            console.log(error);
          });
        //for (var d=new Date();(new Date())-d < 10 * 1000;); / / here is synchronization
        console.log(email,password,'UserService')//How to transmit, what to transmit, what to return and how to return
        }
    reg(name,email,password){
        axios.post('/api/user/reg',{
        name,email,password}
        ).then((response)=> {
            console.log(response.data);
            this.regin=parseInt(Math.random()*100);  //Trigger change
            store.set('token',response.data.token,(new Date()).getTime()+(8*3600*1000));//getTime gets time, but it's milliseconds
        }).catch((error)=> {
            console.log(error.data);
        })
    }
}

The configuration in src/component/reg.js is as follows

import React  from  'react';
import  '../css/login.css'
import  {Link,Redirect}  from  'react-router-dom';
import  UserService   from  '../service/user'
import  {observer}  from  'mobx-react'
const  service= new  UserService();
export  default  class  Reg  extends React.Component{
    render(){
        return  <_Reg    service={service} />; {/*Pass the service here. In the later stage, you can use props.service.xxx to complete the data injection operation.*/}
    }
}
@observer
class   _Reg   extends  React.Component  {
        handleClick(event) {
            event.preventDefault();  //Handle page refresh and block default behavior
            let fm=event.target.form;
            console.log(fm[0].value,fm[1].value,fm[2].value,fm[3].value)  //Get registration information
            this.props.service.reg(fm[0].value,fm[1].value,fm[2].value)
            console.log(this.props.service.regin)
        }
        render() {
            if  (this.props.service.regin)
                return  <Redirect  to='/about' />
          return  (
            <div className="login-page">
                <div  className="form">
                    <form className="register-form">                    
                    <input type="text" placeholder="User name"/>
                    <input type="text" placeholder="mailbox"/>
                    <input type="password" placeholder="Password"/>
                    <input type="password" placeholder="Confirm password"/>
                    <button  onClick={this.handleClick.bind(this)}>register</button>  {/*Trigger button*/}
                    <p className="message">Already registered <Link  to="/reg">Please login</Link></p>
                    </form>
                </div>
            </div>       
           )
        }  
      }

10 add information prompt

In web page development, there are many prompt messages, no matter whether the operation is successful or not. At present, the messages are output from the console, which can not be seen by users. Use the message component of Antd to display friendly message prompts.

1 temporarily modify the index.js page to get the prompt information

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Login  from  './component/login';
import Reg  from  './component/reg';
import { message } from 'antd';
import  'antd/lib/message/style'

const info = () =>{
  message.info('Trigger construction')
}
class Root  extends  React.Component{
  render(){
    return (<div>
      <button  type="prmary"  onClick={info}>Click trigger</button>
    </div>)
  }

}

ReactDom.render(<Root />,document.getElementById('root'));

give the result as follows

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Login  from  './component/login';
import Reg  from  './component/reg';
import { message } from 'antd';
import  'antd/lib/message/style'

const info = () =>{
  message.success('this is first',5)  //5 here is the display delay of 5
}
class Root  extends  React.Component{
  render(){
    return (<div>
      <button  type="prmary"  onClick={info}>Click trigger</button>
    </div>)
  }

}

ReactDom.render(<Root />,document.getElementById('root'));

2 trigger multiple data at the same time

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Login  from  './component/login';
import Reg  from  './component/reg';
import { message } from 'antd';
import  'antd/lib/message/style'

const info = () =>{
  message.success('this is first',5)
  message.info('this is info')
}
class Root  extends  React.Component{
  render(){
    return (<div>
      <button  type="prmary"  onClick={info}>Click trigger</button>
    </div>)
  }

}

ReactDom.render(<Root />,document.getElementById('root'));

give the result as follows

3. Business addition prompt

index.js code restore

The code is modified as follows

import  axios  from  'axios'
import  {observable}  from  'mobx'
import  store  from  'store'
store.addPlugin(require('store/plugins/expire'))  //Load out of date plug-ins, return an object here
//Handling of user logic
export default  class  UserService{
    @observable loggin=0;  //The observed object has been observed. Once the value changes, the observer will know.
    @observable  regin=0;  //Define the observed object of login
    @observable  loginerrMsg='';  //Define the output of login error
    @observable  regerrMsg=''; //Define the output result of registration error 
    login(email,password) {
        axios.post('/api/user/login', {
            'email':  email,
            'password': password
          })
          .then( (response) => {   //The problem of this is solved by arrow function.
            console.log(response,'===================');
            console.log(response.data)
            console.log(response.status);
            //obj.setState({ret:1000}) / / state trigger causes change
            store.set('token',response.data.token,(new Date()).getTime()+(8*3600*1000));//getTime gets time, but it's milliseconds
            this.loggin = Math.random() * 100;  //Modified value
            console.log(this.loggin)

          })
          .catch( (error) => { //Failed action
            console.log(error);  
            this.loginerrMsg=true;  //Triggered when an error occurs
          });
        //for (var d=new Date();(new Date())-d < 10 * 1000;); / / here is synchronization
        console.log(email,password,'UserService')//How to transmit, what to transmit, what to return and how to return
        }
    reg(name,email,password){
        axios.post('/api/user/reg',{
        name,email,password}
        ).then((response)=> {
            console.log(response.data);
            this.regin=parseInt(Math.random()*100);  //Trigger change
            store.set('token',response.data.token,(new Date()).getTime()+(8*3600*1000));//getTime gets time, but it's milliseconds
        }).catch((error)=> {
            this.regerrMsg=true;  //Trigger when an error occurs
            console.log(error.data);
        })
    }
}

The src/component/login.js code is as follows

import React  from  'react';
import  '../css/login.css'
import  {Link,Redirect}  from  'react-router-dom';
import  UserService  from  '../service/user'
import  {observer}   from  'mobx-react'
import { message } from 'antd';
let service  = new  UserService()
export    default  class Login  extends React.Component  {
    render(){
        return  < _Login service={service}/>
    }
}  

@observer
class _Login  extends React.Component{
    handlerClick(event){
        event.preventDefault(); //Its default is to write a data submission once, which is used to prevent its default submission 
        console.log('this----------',this) //this here refers to the Login instance, which can be passed in to modify the ret value to trigger page refresh.
        let  fm=event.target.form
        this.props.service.login(fm[0].value,fm[1].value,this);

    }
    render(){
        if  ( this.props.service.loggin)
            return  <Redirect  to='/about' />
        if  (this.props.service.loginerrMsg)
            {
                message.error('Wrong user name or password',3,()=>{
                    this.props.service.loginerrMsg='';
                })
            }
        return  (
            <div className="login-page">
                <div className="form">
                    <form className="register-form">
                    <input type="text" placeholder="mailbox" defaultValue="12345@123"/>
                    <input type="password" placeholder="Password"  defaultValue="demo"/>
                    <button  onClick={this.handlerClick.bind(this)}>Sign in</button>  {/*Trigger button*/}
                    <p className="message">Not yet registered <Link  to="/reg">Please register</Link></p>
                    </form>
                </div>
            </div>
        )
    }
} 

The src/component/reg.js code is as follows

import React  from  'react';
import  '../css/login.css'
import  {Link,Redirect}  from  'react-router-dom';
import  UserService   from  '../service/user'
import  {observer}  from  'mobx-react'
import { message } from 'antd';
const  service= new  UserService();
export  default  class  Reg  extends React.Component{
    render(){
        return  <_Reg    service={service} />; {/*Pass the service here. In the later stage, you can use props.service.xxx to complete the data injection operation.*/}
    }
}
@observer
class   _Reg   extends  React.Component  {
        handleClick(event) {
            event.preventDefault();  //Handle page refresh and block default behavior
            let fm=event.target.form;
            console.log(fm[0].value,fm[1].value,fm[2].value,fm[3].value)  //Get registration information
            this.props.service.reg(fm[0].value,fm[1].value,fm[2].value)
            console.log(this.props.service.regin)
        }
        render() {
            if  (this.props.service.regin)
                return  <Redirect  to='/about' />
            if (this.props.service.regerrMsg){
                message.error('Registration failed, please check whether the relevant parameters are correct',3,()=>this.props.service.regerrMsg='')
            }
          return  (
            <div className="login-page">
                <div  className="form">
                    <form className="register-form">                    
                    <input type="text" placeholder="User name"/>
                    <input type="text" placeholder="mailbox"/>
                    <input type="password" placeholder="Password"/>
                    <input type="password" placeholder="Confirm password"/>
                    <button  onClick={this.handleClick.bind(this)}>register</button>  {/*Trigger button*/}
                    <p className="message">Already registered <Link  to="/reg">Please login</Link></p>
                    </form>
                </div>
            </div>       
           )
        }  
      }

give the result as follows

Function development of three blog modules

1 interface rules related

/post/put POST submits the title and content of the blog post, and successfully returns the post Ou ID of JSON.

/post/id GET returns the post details. Return JSON's post_id, title, author, author_id, post date (timestamp), content

/post/GET returns the list of Posts

2 upload blog related configuration

1 related documents

https://ant.design/components/layout-cn/

2 front end routing configuration

The code in index.js is as follows

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Login  from  './component/login';
import Reg  from  './component/reg';
import Pub  from  './component/pub'
import  'antd/lib/menu/style'
import  'antd/lib/icon/style'
import  'antd/lib/layout/style'

import { Menu, Icon, Layout,Item} from 'antd'
const { Header, Content, Footer } = Layout;

const  Home =()  => {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
const  About=()  => {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}
class Root  extends  React.Component  {
  render() {
    return  (
          <Router> 
     <div>
     <ul> 
          <li><Link to="/">homepage</Link></li>
          <li><Link to="/about">about</Link></li>
          <li><Link to="/reg">register</Link></li>
          <li><Link to="/login">Sign in</Link></li>
          <li><Link to="/pub">Blog upload</Link></li>

        </ul>

     <Route exact path="/" component={Home} />
     <Route path="/about" component={About} />
     <Route  path="/login" component={Login} />
     <Route  path="/reg" component={Reg} />
     <Route  path="/pub" component={Pub} />

   </div>
 </Router>
  )
  }  
}

ReactDom.render(<Root />,document.getElementById('root'));

3 back end service configuration

service/post.js

import  axios  from  'axios'
import  {observable}  from  'mobx'
import store  from  'store'
export   default   class   PostService   {
    constructor(){
        this.instance=axios.create({
            baseURL:'/api/post',
        });
    }
    @observable  msg="";
    pub(title,content) {
        console.log(title,content)
        this.instance.post('/pub',{
            title,content
        },{
            headers:{'jwt':store.get('token')}
        }).then((response) => {
            console.log(response.data),
            console.log(Response.status);
            this.msg="Blog submitted successfully";  // Trigger event 
        }).catch((error)=> {
            console.log(error.data);
            this.msg="Failed to submit blog";
        })
    }
}

4 rendering page configuration

From form component, layout is vertical, and onsubmit submission. Note that this submission is the form itself.

From item table one way, label set the title of the control, labelCol set the width of the label, wrapperCol is the width occupied by the label, these are the width of the grid system.

INput input field, placeholder prompt character
TextArea textbox, rows
Button button. htmlType uses the type value in HTML. Submit is the submit button will trigger the submit behavior, but this behavior will be blocked in handleSubmit.

/src/component/pub.js

import React  from  'react';
import  '../css/login.css'
import  {Link,Redirect}  from  'react-router-dom';
import  UserService  from  '../service/post'
import  {observer}   from  'mobx-react'
import { Input,message,Button,Form } from 'antd';
import PostService  from  '../service/post'
const  {TextArea}  = Input;
import  'antd/lib/message/style'
import  'antd/lib/form/style'
import  'antd/lib/input/style'
import  'antd/lib/button/style'
export  default  class   Pub   extends  React.Component{
    render(){
        return <_Pub service={new PostService()} />
    }
}  
@observer
class _Pub  extends  React.Component{
    handleSubmit(event){
        event.preventDefault();
        console.log('pub......')
        let  fm=event.target;
        console.log(fm[0].value,fm[1].value)        
        this.props.service.pub(fm[0].value,fm[1].value)
    }
    render(){
        if (this.props.service.failsg)  {
            message.error(this.props.service.msg,5,()=> this.props.service.msg='')
        }
        if (this.props.service.semsg) {
            message.success(this.props.service.semsg,5,()=> this.props.service.semsg='')
        }

                return  (

                        <Form onSubmit={this.handleSubmit.bind(this)} >
                            <Form.Item label="Title" wrapperCol={{span:20}} labelCol={{span:2}}>
                        <Input />
                        </Form.Item>
                            <Form.Item label="content"  wrapperCol={{span:20}} labelCol={{span:2}}>
                        <TextArea  rows={28}/>
                        </Form.Item>
                        <Form.Item   wrapperCol={{span:4,offset:10}}>
                            <Button type="primary" htmlType="submit"  >Release</Button>
                        </Form.Item>
                    </Form>
                    );
                } 
            }

5 the results are as follows

3. View the related configuration and getall of the blog list

1 related documents

ISTIS is needed here. The relevant links are as follows

https://ant.design/components/list-cn/
https://ant.design/components/form-cn/
https://ant.design/components/input-cn/

2 test page data acquisition

Configure render page
Create the Getall.js file in component as follows

import React from 'react';
import { observer } from 'mobx-react';
import PostService from '../service/post';
import 'antd/lib/message/style';
import 'antd/lib/form/style';
import 'antd/lib/input/style';
import 'antd/lib/button/style';

@observer
export  default  class Getall   extends  React.Component{
    constructor(props){
        super(props);
        console.log(props);
    }
    render(){
        return  <h1>Getall</h1>
    }

}

Add it to index.js and the result is as follows

Write http: / / localhost / list? Page = 1 & size = 10 in the input box as follows

As can be seen from the above figure, the props contains the content of the page input box, which is extracted as follows

import React from 'react';
import { observer } from 'mobx-react';
import PostService from '../service/post';
import 'antd/lib/message/style';
import 'antd/lib/form/style';
import 'antd/lib/input/style';
import 'antd/lib/button/style';

@observer
export  default  class Getall   extends  React.Component{
    constructor(props){
        super(props);
        let  {location:{search}}=props;
        console.log(search)  //get data
    }
    render(){
        return  <h1>Getall</h1>
    }

}

give the result as follows

3 display layer code implementation

/The code in src/component/getall.js is as follows

import React from 'react';
import { observer } from 'mobx-react';
import PostService from '../service/post';
import { List, Avatar,Pagination } from 'antd';
import  'antd/lib/list/style'
import  'antd/lib/avatar/style' 
import  'antd/lib/pagination/style'
@observer
export  default  class Getall   extends  React.Component{
    constructor(props){
        super(props);
        let  {location:{search}}=props;
        this.service=new PostService();
        this.service.getall(search);
    }
    handleChange(page,pageSize){
        console.log(page,pageSize)
        let search ='?'+'page='+page+'&'+'size='+pageSize;
        console.log(search)
        this.service.getall(search)
    }
    render(){
        const data=this.service.posts;  //Get data list
        const pagination=this.service.pagination;  //Paging function implementation
        return (
            <div>
            <List
                itemLayout="horizontal"
                dataSource={data}
                bordered="true"
                split="true"
                hideOnSinglePage="true"
                renderItem={item => (
                    <List.Item>
                        <List.Item.Meta
                            avatar={<Avatar src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1571932022162&di=f108eeab8bc4d45e6d9b85c36581f9ae&imgtype=0&src=http%3A%2F%2Fs7.sinaimg.cn%2Fmw690%2F0065sEcMzy74EYHBPMOa6%26690" />}
                            title={item.name}
                            description={item.title}
                        />
                    </List.Item>
                )}
            />
            <Pagination defaultCurrent={1} total={pagination.count} pageSize={pagination.size} onChange={this.handleChange.bind(this)}/>
        </div>

        )
    }
}

4. The logic layer code is as follows

/src/service/post.js

import axios from 'axios'
import { observable } from 'mobx'
import store from 'store'
export default class PostService {
    constructor() {
        this.instance = axios.create({
            baseURL: '/api/post',
        });
    }
    @observable semsg = "";
    @observable failsg = "";
    @observable posts = [];  //Define output results in this container
    @observable pagination = ''; //Define parameter monitoring related to paging function
    pub(title, content) {
        console.log(title, content)
        this.instance.post('/pub', {
            title, content
        }, {
            headers: { 'jwt': store.get('token') }
        }).then((response) => {
            console.log(response.data),
                console.log(Response.status);
            this.semsg = "Blog submitted successfully";  // Trigger event 
        }).catch((error) => {
            console.log(error.data);
            this.failsg = "Failed to submit blog";
        })
    }
    getall(search) {
        axios.get('/api/post/' + search).then(
            response => {
                console.log(response.data)
                this.posts = response.data.posts; //Successful output
                this.pagination = response.data.pagination;   //Relevant parameters carried
            }
        ).catch(error=> {
            console.log(error.data)
        })
    }
} 

give the result as follows

4 details page get configuration

1 get id data

import React from 'react';
import { observer } from 'mobx-react';
import PostService from '../service/post';
import { Card,Row } from 'antd';
export default  class Get  extends  React.Component{
    constructor(props){
        super(props);
        this.service=new PostService();
        console.log(props);
    }
    render(){
        return  (<div>  Get </div>)    
    }
}

The results of adding it to index.js are as follows

As we know above, the id acquisition is still completed through pathname, and the specific code is as follows

2. The code of view layer is as follows

/src/component/get.js

import React from 'react';
import { observer } from 'mobx-react';
import PostService from '../service/post';
import { Card,Row, message } from 'antd';
import  'antd/lib/card/style'
@observer
export default  class Get  extends  React.Component{
    constructor(props){
        super(props);
        this.service=new PostService();
        let  {location:{pathname}}=this.props;
        let [,,id]=pathname.split('/')  // Get ID 
        this.service.get(id)  //Asynchronous value transfer to back end
    }
    render(){
        let s=this.service;
        if  (s.getMsg) {
            message.error("Failed to get article",3,()=> s.getMsg=false)
        }
        let post=s.post;
        return  <Card  title={post.title}  bordered={true} style={{width:600}}>
                    <p>{post.author} {new Date(post.postdate*1000).toLocaleDateString()} </p>
                    <p>{post.content}</p>
        </Card>  
        }
    }

3. Business layer code is as follows

/src/service/post.js

import axios from 'axios'
import { observable } from 'mobx'
import store from 'store'
export default class PostService {
    constructor() {
        this.instance = axios.create({
            baseURL: '/api/post',
        });
    }
    @observable semsg = "";
    @observable failsg = "";
    @observable posts = [];  //Define output results in this container
    @observable pagination = ''; //Define parameter monitoring related to paging function
    @observable  post='';  //Define the detailed page data obtained by get
    @observable  getMsg=false;// Define whether get gets data successfully and returns to processing
    pub(title, content) {
        console.log(title, content)
        this.instance.post('/pub', {
            title, content
        }, {
            headers: { 'jwt': store.get('token') }
        }).then((response) => {
            console.log(response.data),
                console.log(Response.status);
            this.semsg = "Blog submitted successfully";  // Trigger event 
        }).catch((error) => {
            console.log(error.data);
            this.failsg = "Failed to submit blog";
        })
    }
    getall(search) {
        axios.get('/api/post/' + search).then(
            response => {
                console.log(response.data)
                this.posts = response.data.posts; //Successful output
                this.pagination = response.data.pagination;   //Relevant parameters carried
            }
        ).catch(error=> {
            console.log(error.data)
        })
    }
    get(id){
        axios.get('/api/post/'+id).then(response =>{
            console.log(response.data)
            this.post=response.data.post;
        }).catch(error => {
            console.log(error.data)    
            this.getMsg=true;

        })
    }
} 

give the result as follows

5 jump to details page through getall page

Jump to localhost/get/x through the post_id obtained in getall

import React from 'react';
import { observer } from 'mobx-react';
import PostService from '../service/post';
import { List, Avatar,Pagination,Link } from 'antd';
import  'antd/lib/list/style'
import  'antd/lib/avatar/style' 
import  'antd/lib/pagination/style'
@observer
export  default  class Getall   extends  React.Component{
    constructor(props){
        super(props);
        let  {location:{search}}=props;
        this.service=new PostService();
        this.service.getall(search);
    }
    handleChange(page,pageSize){
        console.log(page,pageSize)
        let search ='?'+'page='+page+'&'+'size='+pageSize;
        console.log(search)
        this.service.getall(search)
    }
    render(){
        const data=this.service.posts;  //Get data list
        const pagination=this.service.pagination;  //Paging function implementation
        return (
            <div>
            <List
                itemLayout="horizontal"
                dataSource={data}
                bordered="true"
                split="true"
                hideOnSinglePage="true"
                renderItem={item => (
                    <List.Item>
                        <List.Item.Meta
                            avatar={<Avatar src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1571932022162&di=f108eeab8bc4d45e6d9b85c36581f9ae&imgtype=0&src=http%3A%2F%2Fs7.sinaimg.cn%2Fmw690%2F0065sEcMzy74EYHBPMOa6%26690" />}
                            title={<a href={'/get/'+item.post_id}>{item.title}</a>}
                            description={item.title}
                        />
                    </List.Item>
                )}
            />
            <Pagination defaultCurrent={1} total={pagination.count} pageSize={pagination.size} onChange={this.handleChange.bind(this)}/>
        </div>

        )
    }
}

give the result as follows

4 high level component decorator

1 basic code overview

Here, a class is passed in and a class is returned.

function inject(Comp)  {
    return  class  extends  React.Component {
        render(){
            return  <Comp service={service} />
        }
    }
}

The extraction parameters are as follows

function inject(Comp,service) {
    return  class extends  React.Component{
    render() {
        return  <Comp service={service} />
    }
    }
}

Processing with variable parameters

function  inject(...obj,Comp){
    return  class  extends  React.Component{
        render(){
            return  <Comp  {...obj} />
        }
    }
}

currying

function  inject(obj){
    function wrapper(Comp)  {
        return  class  extends  React.Component{
            render(){
                return  <Comp  {...obj} />
            }
        }
    }
    return wrapper;
} 

deformation

function  inject(obj){
    return  function wrapper(Comp)  {
        return class  extends  React.Component{
            render(){
                return  <Comp {...obj} />
            }
        }
    }
}

Arrow function deformation

const  inject  = obj => Comp => {
    return class  extends  React.Component{
        render(){
            return  <Comp {...obj} />
        }
    }
}

Functional component simplification

const insject = obj=> Comp=> {
    return  props => <Comp {...obj} />
}

Continue to simplify as follows

const insject = obj=> Comp =>  props => <Comp {...obj}  {...props} />

2. Create an external function to handle the incoming problem of service

Create the utils.js file in the same directory as src, as follows

import React  from  'react';
const insject = obj=> Comp =>  props => <Comp {...obj} {...props}/>
export  {insject}

3 modify the login and registration view code

/src/component/login.js

import React  from  'react';
import  '../css/login.css'
import  {Link,Redirect}  from  'react-router-dom';
import  UserService  from  '../service/user'
import  {observer}   from  'mobx-react'
import { message } from 'antd';
let service  = new  UserService()
import { insject } from "../utils";
@insject({service})
@observer
export default class   Login  extends React.Component{
    handlerClick(event){
        event.preventDefault(); //Its default is to write a data submission once, which is used to prevent its default submission 
        console.log('this----------',this) //this here refers to the Login instance, which can be passed in to modify the ret value to trigger page refresh.
        let  fm=event.target.form
        this.props.service.login(fm[0].value,fm[1].value,this);
    }
    render(){
        if  ( this.props.service.loggin)
            return  <Redirect  to='/getall' />
        if  (this.props.service.loginerrMsg)
            {
                message.error('Wrong user name or password',3,()=>{
                    this.props.service.loginerrMsg='';
                })
            }
        return  (
            <div className="login-page">
                <div className="form">
                    <form className="register-form">
                    <input type="text" placeholder="mailbox" defaultValue="12345@123"/>
                    <input type="password" placeholder="Password"  defaultValue="demo"/>
                    <button  onClick={this.handlerClick.bind(this)}>Sign in</button>  {/*Trigger button*/}
                    <p className="message">Not yet registered <Link  to="/reg">Please register</Link></p>
                    </form>
                </div>
            </div>
        )
    }
} 

/src/component/reg.js

import React  from  'react';
import  '../css/login.css'
import  {Link,Redirect}  from  'react-router-dom';
import  UserService   from  '../service/user'
import  {observer}  from  'mobx-react'
import { message } from 'antd';
import { insject } from "../utils";

const  service= new  UserService();

@insject({service})
@observer
export default class   Reg   extends  React.Component  {
        handleClick(event) {
            event.preventDefault();  //Handle page refresh and block default behavior
            let fm=event.target.form;
            console.log(fm[0].value,fm[1].value,fm[2].value,fm[3].value)  //Get registration information
            this.props.service.reg(fm[0].value,fm[1].value,fm[2].value)
            console.log(this.props.service.regin)
        }
        render() {
            if  (this.props.service.regin)
                return  <Redirect  to='/about' />
            if (this.props.service.regerrMsg){
                message.error('Registration failed, please check whether the relevant parameters are correct',3,()=>this.props.service.regerrMsg='')
            }
          return  (
            <div className="login-page">
                <div  className="form">
                    <form className="register-form">                    
                    <input type="text" placeholder="User name"/>
                    <input type="text" placeholder="mailbox"/>
                    <input type="password" placeholder="Password"/>
                    <input type="password" placeholder="Confirm password"/>
                    <button  onClick={this.handleClick.bind(this)}>register</button>  {/*Trigger button*/}
                    <p className="message">Already registered <Link  to="/reg">Please login</Link></p>
                    </form>
                </div>
            </div>       
           )
        }  
      }

5 add layout to index.js page

1 relevant documents are as follows

https://ant.design/components/layout-cn/

2 the specific code is as follows

import React from 'react';
import ReactDom from 'react-dom';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Login  from  './component/login';
import Reg  from  './component/reg';
import Pub  from  './component/pub'
import Get  from  './component/get'
import Getall  from  './component/Getall';

import  'antd/lib/menu/style'
import  'antd/lib/icon/style'
import  'antd/lib/layout/style'

import { Layout, Menu,Icon } from 'antd';

const { Header, Content, Footer } = Layout;

import  'antd/lib/layout/style'
import  'antd/lib/menu/style'

const  Home =()  => {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
class Root  extends  React.Component  {
  render() {
    return  (
      <Router>
      <Layout>
      <Header   style={{ position: 'fixed', zIndex: 1, width: '100%' }} >
        <div className="logo" />
        <Menu theme="dark"
          mode="horizontal"
          defaultSelectedKeys={['1']}
          style={{ lineHeight: '65px' }}>
          <Menu.Item key="home">
                  <Link to="/"><Icon type="home" /> homepage</Link>
                </Menu.Item>
          <Menu.Item key="login">
                  <Link to="/login"><Icon type="login" />Land</Link>
           </Menu.Item>    
        <Menu.Item key="reg">
                  <Link to="/reg"><Icon type="home" />register</Link>
           </Menu.Item>  
           <Menu.Item key="pub">
                  <Link to="/pub"><Icon type="home" />upload</Link>
           </Menu.Item> 
        <Menu.Item key="getall">
                  <Link to="/getall"><Icon type="home" />List view</Link>
           </Menu.Item> 
      <Menu.Item key="get">
                  <Link to="/get"><Icon type="bars" />Details page</Link>
           </Menu.Item> 
        </Menu>
      </Header>
     <h1></h1>
     <h1></h1>
     <h1></h1>
     <h1></h1>
     <h1></h1>

      <Content style={{ padding: '5px  20px' }}>
              <div style={{ background: '#fff', padding:  30, minHeight: 50}}>
                <Route  exact path="/" component={Home} />
                <Route  path="/login"  component={Login} />
                <Route  path="/reg"    component={Reg} />
                <Route  path="/pub"    component={Pub} />
                <Route  path="/getall"    component={Getall} />
                <Route  path="/get"    component={Get} />

              </div>
         </Content>
        <Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
      </Layout>
      </Router>
  )
  }  
}

ReactDom.render(<Root />,document.getElementById('root'));

give the result as follows

So far, the front-end page development is completed

Topics: Javascript React axios npm github