The react based

Create projects with react scaffolding

npx create-react-app my-app
Copy the code

Then open the app.js file and delete the excess

function App() {
  return (
    <div >
          <h1>hello react</h1>
    </div>
  );
}

export default App;

Copy the code

JSX

Before learning how to operate, we should first understand the JSX syntax, like app.js like JavaScript and HTML syntax is JSX, some basic rules of writing above

1. There is only one root element

2, class uses className

3, the style format is style={{attribute: value}}, attributes should be named with small hump

4. Insert values with {}


const No = {
  name: 'don't forget'.age: 'the'
}

function App() {
  return (
    <div >
      <h1>hello react</h1>
      <p>{No. Name} has many wives, this year {No. Age}</p>
      <ul>
    </div>
  );
}

export default App;

Copy the code

5. You can also add some expressions


const No = {
  name: 'don't forget'.age: 'the'.girlfriend: ['ice ice'.'jia jia'.'Lin Lin']}function App() {
  return (
    <div >
      <h1>hello react</h1>
      <p>{No. Name} has many wives, this year {No. Age}</p>
      <ul>
        <li>My girlfriend has:</li>
        {
          No.girlfriend.map((value,index)=>{
            return <li key={index}>{value}</li>})}</ul>
        {
          No.age>18? <h1>Ready to get married</h1> : <h1>Marry when you are of age</h1>
        }
    </div>
  );
}

export default App;

Copy the code

6. Tags that start in lowercase are converted to HTML tags, and tags that start in uppercase are converted to components

function App() {
  return (
    <div >
      <h1>hello react</h1>
        <Dream />
    </div>
  );
}

function Dream() {
  return (
    <h2>What is the difference between a man and a salted fish if he has no dreams</h2>)}export default App;

Copy the code

component

Functional component

function App() {
  return (
    <div >
      <h1>hello react</h1>
    </div>
  );
}

Copy the code

Class components

class App extends React.Component{
  render() {
    return (
      <div>
        <h1>hello</h1>
      </div>
    );
  };
};

Copy the code

Note that the component name starts with a capital letter

Three properties of a component instance

state

basis

class App extends React.Component{
  constructor(props) {
    super(props);
    this.state = {msg: 'Heaven and earth are dark and yellow. The sun moon surplus, Chen Night column Zhang. '}}render() {
    return (
      <div>
        <h1>hello</h1>
        <h2>{this.state.msg}</h2>
      </div>
    );
  };
};
Copy the code

Optimization of a bit

class App extends React.Component{
  constructor(props) {
    super(props);
    this.state = {msg: 'Heaven and earth are dark and yellow. The sun moon surplus, Chen Night column Zhang. '}}render() {
    const {msg} = this.state;
    return (
      <div>
        <h1>hello</h1>
        <h2>{msg}</h2>
      </div>
    );
  };
};

Copy the code

Change the state

Involving event calls, see directory click events

class App extends React.Component{
  constructor(props) {
    super(props);
    this.state = {msg: 'Heaven and earth are dark and yellow. The sun moon surplus, Chen Night column Zhang. '.show: true}
    this.change=this.change.bind(this)}render() {
    const {msg,show} = this.state;
    return (
      <div>
        <h1>hello</h1>
        <button onClick={this.change}>{! show? 'Appear ':' disappear '}</button>
        <h2>{show? msg :''}</h2>
      </div>
    );
  };

  change(){
    this.setState({show:!this.state.show});// To change state, call setState}};Copy the code

To optimize the

class App extends React.Component{
  
  state = {msg: 'Heaven and earth are dark and yellow. The sun moon surplus, Chen Night column Zhang. '.show: true}
  
  render() {
    const {msg,show} = this.state;
    return (
      <div>
        <h1>hello</h1>
        <button onClick={this.change}>{! show? 'Appear ':' disappear '}</button>
        <h2>{show? msg :''}</h2>
      </div>
    );
  };

  change=() = > {
    this.setState({show:!this.state.show});// To change state, call setState}};Copy the code

props

Basic usage

class App extends React.Component{
  render() {
    return (
      <div >
        <Dream name="Never forget" girlfriend="Ice ice"/>
        <br/>
        <br/>
        <Dream name="Memories" girlfriend="Cui flower"/>
    </div>
    );
  };
};

class Dream extends React.Component{
  render() {
    return (
      <div>
        <h1>hello {this.props.name}</h1>
        <h2>Your wife {this.props. Girlfriend} is here</h2>
      </div>
    );
  };
};

Copy the code

To optimize the

class App extends React.Component{
  render() {
    const no={name: "Never forget".girlfriend:'ice ice'}
    const yes={name: "Memories".girlfriend:'cui flower'}
    return (
      <div >
        <Dream {. no} / >
        <br/>
        <br/>
        <Dream {. yes} / >
    </div>
    );
  };
};

class Dream extends React.Component{
  render() {
    const {name,girlfriend}=this.props;
    return (
      <div>
        <h1>hello {name}</h1>
        <h2>Your wife is here</h2>
      </div>
    );
  };
};
Copy the code

Props to limit

[email protected] or later

Under the bag

npm i prop-types --save
Copy the code

The import

import PropTypes from 'prop-types';
Copy the code

use

class App extends React.Component{
  render() {
    const no={name: "Never forget".girlfriend:'ice ice'}
    const yes={name: "Memories".girlfriend:'cui flower'}
    return (
      <div >
        <Dream {. no} / >
        <br/>
        <br/>
        <Dream {. yes} / >
    </div>
    );
  };
};

function Dream(props) {
    const {name,girlfriend,msg}=props;
    return (
      <div>
        <h1>hello {name}</h1>
        <h2>Your wife is here</h2>
        <p>{msg}</p>
      </div>
    );
};

Dream.propTypes={
  name: PropTypes.string,
}

Dream.defaultProps={
  msg:'Jumped for joy'
}

Copy the code

To optimize the

class App extends React.Component{
  render() {
    const no={name: "Never forget".girlfriend:'ice ice'}
    const yes={name: "Memories".girlfriend:'cui flower'}
    return (
      <div >
        <Dream {. no} / >
        <br/>
        <br/>
        <Dream {. yes} / >
    </div>
    );
  };
};

class Dream extends React.Component{
  static propTypes = {// Restrict the type
    name: PropTypes.string,
  }

  static defaultProps = {// Set the default value
    msg:'Jumped for joy'
  }
  render() {
    const {name,girlfriend,msg}=this.props;
    return (
      <div>
        <h1>hello {name}</h1>
        <h2>Your wife is here</h2>
        <p>{msg}</p>
      </div>
    );
  };
};

Copy the code

Common restrictions are

Array: an array

Boolean: the Boolean

Function: func

The Numbers: number

Object: the object

String: string

Props for functional components

class App extends React.Component{
  render() {
    const no={name: "Never forget".girlfriend:'ice ice'}
    const yes={name: "Memories".girlfriend:'cui flower'}
    return (
      <div >
        <Dream {. no} / >
        <br/>
        <br/>
        <Dream {. yes} / >
    </div>
    );
  };
};

function Dream(props) {
    const {name,girlfriend,msg}=props;
    return (
      <div>
        <h1>hello {name}</h1>
        <h2>Your wife is here</h2>
        <p>{msg}</p>
      </div>
    );
};

Copy the code

refs

Use as little as you can

String ref(preferably not)


class App extends React.Component{
  showData=() = >{
    const {data} = this.refs;
    console.log(data.value);
  }
  render() {
    return (
      <div >
       <input onBlur={this.showData} type="text" ref="data" name="" id="" placeholder="Enter query content"/>
      </div>
    );
  };
};
Copy the code

The callback function ref

class App extends React.Component{
  showData=() = >{
    const {data} = this;
    console.log(data.value);
  }
  render() {
    return (
      <div >
       <input onBlur={this.showData} type="text" ref={value= >This. data=value; placeholder= value; placeholder= value;</div>
    );
  };
};
Copy the code

Kind of binding


class App extends React.Component{
  showData=() = >{
     const {data}=this;
    console.log(data.value);
  }
  saveInput=(value) = >{
    this.data=value;
  }
  render() {
    return (
      <div >
       <input onBlur={this.showData} type="text" ref={this.saveInput} name="" id="" placeholder="Enter query content"/>
      </div>
    );
  };
};
Copy the code

CractRef (recommended)

class App extends React.Component{
  saveRef=React.createRef()
  showData=() = >{
    console.log(this.saveRef.current.value);
  }
  render() {
    return (
      <div >
       <input onBlur={this.showData} type="text" ref={this.saveRef} name="" id="" placeholder="Enter query content"/>
      </div>
    );
  };
};
Copy the code

The event

The event name is onXxxx, with the first letter after on capitalized

Delegate mode is mounted on the outermost element

The DOM of the occurring object can be obtained via event.target

class App extends React.Component{
  showData=(event) = >{
    console.log(event.target.value);
  }
  render() {
    return (
      <div >
       <input onBlur={this.showData} type="text" name="" id="" placeholder="Enter query content"/>
      </div>
    );
  };
};

Copy the code

To obtain parameters

Before you get the parameters, there’s a concept called currification of a function

The way that the parameters of a called function are treated uniformly in the return function is called function corrification

class App extends React.Component{
  state={msg:' '.find:' '}
  showData=(data) = >{
    return (event) = > {
      this.setState({[data]:event.target.value});
      this.setState({msg:data}); }}render() {
    const {msg,find} = this.state
    return (
      <div >
       <input onChange={this.showData('find')} type="text" name="" id="" placeholder="Enter query content"/>
       <h1>{msg}</h1>
       <p>{find}</p>
      </div>
    );
  };
};

Copy the code

You don’t have to do that

class App extends React.Component{
  state={msg:' '.find:' '}
  showData=(data,event) = >{
      this.setState({[data]:event.target.value});
      this.setState({msg:data});
    }
  render() {
    const {msg,find} = this.state
    return (
      <div >
       <input onChange={(event)= >This. ShowData ('find',event)} placeholder=" placeholder "; placeholder=" placeholder ";<h1>{msg}</h1>
       <p>{find}</p>
      </div>
    );
  };
};
Copy the code

Controlled component, uncontrolled component

Basically, there is no state to store data

Uncontrolled component

class App extends React.Component{
  showData=(event) = >{
    console.log(event.target.value);
  }
  render() {
    return (
      <div >
       <input onBlur={this.showData} type="text" name="" id="" placeholder="Enter query content"/>
      </div>
    );
  };
};

Copy the code

The controlled components

class App extends React.Component{
  state={msg:' '}
  showData=(event) = >{
    this.setState({msg:event.target.value});
  }
  render() {
    const {msg} = this.state
    return (
      <div >
       <input onChange={this.showData} type="text" name="" id="" placeholder="Enter query content"/>
       <h1>{msg}</h1>
      </div>
    );
  };
};
Copy the code

Component life cycle

To briefly demonstrate the new lifecycle function, there are three scenarios

Initialization phase

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class App extends Component{
  constructor(props) {
    super(props);
    this.state = {msg: 'Heaven and earth are dark and yellow. The sun moon surplus, Chen Night column Zhang. '}}render() {
    return (
      <div>
        <h1>hello</h1>
        <div id="children">
          <Children msg={this.state.msg}/>
        </div>
      </div>
    );
  };
};

class Children extends Component{
  constructor(props) {
    console.log('constructor');
    super(props);
    this.state={}
  }
  static getDerivedStateFromProps(The props, the state) {
    console.log('getDerivedStateFromProps', props, state);return props // Convert the value of state to the accepted props, returning unll without sending changes
  }

  componentDidMount(){
    console.log('componentDidMount');// Common write components from the beginning of the function, network loading, timer, etc
  }
  render() {
    console.log('render');
    return (
      <div>
        <h2>{this.state.msg}</h2>
        <h2>{this.props.msg}</h2>
      </div>
    );
  };
};


export default App;
Copy the code

Update the stage

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class App extends Component{
  constructor(props) {
    super(props);
    this.state = {msg: 'Heaven and earth are dark and yellow. The sun moon surplus, Chen Night column Zhang. '}}render() {
    return (
      <div>
        <h1>hello</h1>
        <div id="children">
          <Children msg={this.state.msg}/>
        </div>
      </div>
    );
  };
};

class Children extends Component{
  state={mage:' '}

  static getDerivedStateFromProps(props,state){
    console.log('getDerivedStateFromProps',props,state);
      return null 
  }

  shouldComponentUpdate(){
    console.log('shouldComponentUpdate');
    return true
    // Return true to update, false not to update
  }

  getSnapshotBeforeUpdate(preProps,preState){
    console.log('getSnapshotBeforeUpdate',preProps,preState);
    return 'Value from getSnapshotBeforeUpdate'
    // The value returned by componentDidUpdate will be received
  }

  componentDidUpdate(preProps,preState,val){
    console.log('componentDidUpdate',preProps,preState,val);
    // Props, state, and return values from getSnapshotBeforeUpdate before changing
  }

  change=() = > {
    this.setState({msge:'Seasons come and goes, autumn harvests and winter hides. Leap more than into the age, lv Yang '})}render() {
    console.log('render');
    return (
      <div>
        <h2>{this.props.msg}</h2>
        <h2>{this.state.msge}</h2>
        <button onClick={this.change}>change</button>
      </div>
    );
  };
};


export default App;
Copy the code

Uninstall the component

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class App extends Component{
state = {msg: 'Heaven and earth are dark and yellow. The sun moon surplus, Chen Night column Zhang. '}

componentWillMount() {
  console.log('componentWillMount');// Execute before uninstallation
}

  remove=() = > {
    ReactDOM.unmountComponentAtNode(document.getElementById('root'));// Uninstall the component
  }
  render() {
    return (
      <div>
        <h1>hello</h1>
        <h2>{this.state.msg}</h2>

        <button onClick={this.remove}>uninstall</button>
      </div>
    );
  };
};


export default App;
Copy the code

Diffing algorithm

The Diffing algorithm is used to compare the virtual DOM and the real DOM. When the virtual DOM changes, different parts of the real DOM are modified

In the virtual DOM, key is the unique identifier of the virtual DOM. If an element with the same key is compared and the content of the real DOM is changed differently, if the real DOM does not use the key element of the virtual DOM, the corresponding element will be created

When index is used as the key, sequential operations, such as adding and deleting objects in reverse order, affect efficiency

An error occurs if the DOM is included in the input


class App extends React.Component{
  state={data:[
    {name:'don't forget'.age:20},
    {name:'memories'.age:18},
  ]}

  add=() = >{
    this.setState({data: [{name:'as a souvenir.age:19},
      {name:'don't forget'.age:20},
      {name:'memories'.age:18})}},]render() {
    const {data} = this.state
    return (
      <div >
        <button onClick={this.add}>add</button>
      {
        data.map(val=>{
          return (
            <h1>{val.name} {val.age}<input type="text"/></h1>)})}</div>
    );
  };
};
// When you enter the input field and click Add, you will find that the input field does not correspond to the previous value
Copy the code

Proxy Server Configuration

Create setupproxy.js under SRC

const { proxy } = require('http-proxy-middleware')
/ / or
// const proxy = require('http-proxy-middleware')

module.exports = function (app) {
  app.use(proxy('/api', {
    target: 'http://172.16.136.249:8080'.secure: false.changeOrigin: true.pathRewrite: {
      "^/api": "/api"}}}))Copy the code

Routing (DOM)

Based on using

Download package

npm i react-router-dom
Copy the code

Open index. Js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {BrowserRouter} from 'react-router-dom';
// Import BrowserRouter, as a component nested App component, using history mode, and HasRouter hash mode
ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>.document.getElementById('root'));// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Copy the code

Open the App. Js

import React from 'react';
import {Link,Route} from 'react-router-dom';
import {no} from './index/no.jsx'
import {yes} from './index/yes'

class App extends React.Component{
  render() {
    return (
      <div >
        <Link to="/no" >A wife who never forgets</Link>{/*Link component set click to jump path, to is the jump path */}<br/>
        <Link to="/yes" >Wife of memory</Link>
       <br/>
          <Route path="/no" component={no}/>{/*Route sets the jump content, path is the jump path, component is the jump content */}<Route path="/yes" component={yes}/>
       
      </div>
    );
  };
};


export default App;

Copy the code

Create the index folder and create No. JSX and yes.jsx

no.jsx


import React from 'react';

export class no extends React.Component{
  render() {
    return (
      <div>
        <h1>Ice ice</h1>
      </div>
    );
  };
};
Copy the code

yes.jsx


import * as React from 'react';

export class yes extends React.Component{
  render() {
    return (
      <div>
        <h1>Such as flower</h1>
      </div>
    );
  };
};
Copy the code

Routing component

JSX and yes. JSX, like the ones above, are part of the routing component

Look at the properties of the routing component props

history

localtion

matchactive

NavLink

If you define a class name activeClassName, it will be automatically added when you click on it. If you click on another class name activeClassName, it will be automatically deleted

Modify the App. Js

import React from 'react';
import './App.css'
import {NavLink,Route} from 'react-router-dom';
import {no} from './index/no.jsx'
import {yes} from './index/yes'

class App extends React.Component{
  render() {
    return (
      <div >
        <NavLink activeClassName="ch" to="/no" >A wife who never forgets</NavLink>
        <br/>
        <NavLink activeClassName="ch"  to="/yes" >Wife of memory</NavLink>
       <br/>
          <Route path="/no" component={no}/>
          <Route path="/yes" component={yes}/>
       
      </div>
    );
  };
};


export default App;

Copy the code

Modify the App. CSS

.active{
    color: red;
}

.ch{
    font-size: 30px;
}
Copy the code

Switch

When a route is matched, the route is not matched downward

Modify the App. Js

import React from 'react';
import './App.css'
import {NavLink,Route,Switch} from 'react-router-dom';
import {no} from './index/no.jsx'
import {yes} from './index/yes'

class App extends React.Component{
  render() {
    return (
      <div >
        <NavLink activeClassName="ch" to="/no" >A wife who never forgets</NavLink>
        <br/>
        <NavLink activeClassName="ch"  to="/yes" >Wife of memory</NavLink>
       <br/>
       <Switch>
          <Route path="/no" component={no}/>
          <Route path="/yes" component={yes}/>
       </Switch>
      </div>
    );
  };
};


export default App;

Copy the code

Fuzzy matching

For example, when the route is the same, the following child routes will still get the information of the current route

import React from 'react';
import './App.css'
import {NavLink,Route,Switch} from 'react-router-dom';
import {no} from './index/no.jsx'
import {yes} from './index/yes'

class App extends React.Component{
  render() {
    return (
      <div >
        <NavLink activeClassName="ch" to="/no/suiyi" >A wife who never forgets</NavLink>
        <br/>
        <NavLink activeClassName="ch"  to="/yes" >Wife of memory</NavLink>
       <br/>
       <Switch>
          <Route path="/no" component={no}/>
          <Route path="/yes" component={yes}/>
       </Switch>
      </div>
    );
  };
};


export default App;
Copy the code

To enable precise matching, you need exactly the same route

import React from 'react';
import './App.css'
import {NavLink,Route,Switch} from 'react-router-dom';
import {no} from './index/no.jsx'
import {yes} from './index/yes'

class App extends React.Component{
  render() {
    return (
      <div >
        <NavLink activeClassName="ch" to="/no" >A wife who never forgets</NavLink>
        <br/>
        <NavLink activeClassName="ch"  to="/yes" >Wife of memory</NavLink>
       <br/>
       <Switch>
       	  <Route exact path="/no" component={no}/>{/*exact start exact match */}<Route path="/yes" component={yes}/>
       </Switch>
      </div>
    );
  };
};


export default App;
Copy the code

Redirect

Redirect is sent when none of the routes match

import React from 'react';
import './App.css'
import {NavLink,Route,Switch,Redirect} from 'react-router-dom';
import {no} from './index/no.jsx'
import {yes} from './index/yes'
import {noFind} from './index/nofind'

class App extends React.Component{
  render() {
    return (
      <div >
        <NavLink activeClassName="ch" to="/no" >A wife who never forgets</NavLink>
        <br/>
        <NavLink activeClassName="ch"  to="/yes" >Wife of memory</NavLink>
        <br/>
        <NavLink activeClassName="ch"  to="/nover" >Your wife</NavLink>
       <br/>
       <Switch>
          <Route path="/no" component={no}/>
          <Route path="/yes" component={yes}/>
          <Route path="/notFind" component={noFind}/>
          <Redirect to="/notFind"/>{/* Redirect to notFind path */}</Switch>
      </div>
    );
  };
};


export default App;

Copy the code

Nested routing

Open no. JSX


import React from 'react';
import {Link,Route} from 'react-router-dom'
import binbin from './noGirl/binbin'
import jiajia from './noGirl/jiajia'

export class no extends React.Component{
  render() {
    return (
      <div>
        <Link to="/no/binbin" className="next">Ice ice</Link>
        <Link to="/no/jiajia" className="next">Jia jia</Link>{/* The name of the path must include the content of the parent route */}<Route path="/no/binbin" component={binbin}/>
        <Route path="/no/jiajia" component={jiajia}/>
      </div>
    );
  };
};
Copy the code

Create the noGirl folder and then create binbin.jsx and jiajia.jsx

binbin.jsx

import React, { Component } from 'react';

class binbin extends Component {
    render() {
        return (
            <div>
                <p>character</p>
                <p>hobby</p>
                <p>photo</p>
            </div>); }}export default binbin;
Copy the code

jiajia.jsx

import React, { Component } from 'react';

class jiajia extends Component {
    render() {
        return (
            <div>
                <p>height</p>
                <p>weight</p>
                <p>age</p>
            </div>); }}export default jiajia;
Copy the code

Routing with parameters

Params mass participation

Look at the no. JSX


import React from 'react';
import {Link,Route} from 'react-router-dom'
import girl from './girl'

export class no extends React.Component{
  render() {
    return (
      <div>
        <Link to="/no/1" className="next">The first wife</Link>
        <Link to="/no/2" className="next">Second wife</Link>{/* Add arguments */}<Route path="/no/:id" component={girl}/>{/* Pass */ as / : argument / : argument}</div>
    );
  };
};
Copy the code

Then modify girl.jsx

import React, { Component } from 'react';

class girl extends Component {
    state={girl:[
        {id:1.name: "Ice ice"},
        {id:2.name: "Jia jia"}}]render() {
        let {girl}=this.state;
        const {id}=this.props.match.params;
        // Accept at this.props. Match.params
        const c=girl.find(value= > {
            return value.id===id-0
        })
        return (
            <div>
               <h1>
                {c.name}
               </h1>
            </div>); }}export default girl;
Copy the code

Serch the participation

Modification of no. JSX


import React from 'react';
import {Link,Route} from 'react-router-dom'
import girl from './girl'

export class no extends React.Component{
  render() {
    return (
      <div>
        <Link to="/no/? Id =1&msg= very nice" className="next">The first wife</Link>
        <Link to="/no/? Id =2& MSG = very cute" className="next">Second wife</Link>{/ *? Attribute = value & attribute = value pass */}<Route path="/no" component={girl}/>
      </div>
    );
  };
};
Copy the code

Modify the girl. JSX

import React, { Component } from 'react';
import qs from 'querystring'

class girl extends Component {
    state={girl:[
        {id:1.name: "Ice ice"},
        {id:2.name: "Jia jia"}}]render() {
        let {girl}=this.state;
        const {search}=this.props.location;
        {/* Receive parameters */}
        const data=qs.parse(search);
        {/* becomes the object */}
        const c=girl.find(value= > {
            return value.id===data['? id'] -0
        })
        console.log(data['? id']);
        return (
            <div>
               <h1>
                {c.name}
               </h1>
               <p>{data.msg}</p>
            </div>); }}export default girl;
Copy the code

The state transfer and

Modification of no. JSX


import React from 'react';
import {Link,Route} from 'react-router-dom'
import girl from './girl'

export class no extends React.Component{
  render() {
    return (
      <div>
        <Link to={{pathname:'/no',state:{id:1.msg:'Very nice '}}}className="next">The first wife</Link>
        <Link to={{pathname:'/no',state:{id:2.msg:'Very cute '}}}className="next">Second wife</Link>

        <Route path="/no" component={girl}/>
      </div>
    );
  };
};
Copy the code

Modify the girl. JSX

import React, { Component } from 'react';
import qs from 'querystring'

class girl extends Component {
    state={girl:[
        {id:1.name: "Ice ice"},
        {id:2.name: "Jia jia"}}]render() {
        let {girl}=this.state;
        const {id,msg}=this.props.location.state || {};
        const c=girl.find(value= > {
            return value.id===id-0}) | | {}return (
            <div>
               <h1>
                {c.name}
               </h1>
               <p>{msg}</p>
            </div>); }}export default girl;
Copy the code

Push and replace

Push leaves a history and can be returned, replace has no record and cannot be returned

Open the app. Js

import React from 'react';
import './App.css'
import {NavLink,Route,Switch,Redirect} from 'react-router-dom';
import {no} from './index/no.jsx'
import {yes} from './index/yes'
import {noFind} from './index/nofind'

class App extends React.Component{
  render() {
    return (
      <div >
        <NavLink replace activeClassName="ch" to="/no" >A wife who never forgets</NavLink>{/*replace Enable routing */}<br/>
        <NavLink replace activeClassName="ch"  to="/yes" >Wife of memory</NavLink>
        <br/>
        <NavLink replace activeClassName="ch"  to="/nover" >Your wife</NavLink>
       <br/>
       <Switch>
          <Route path="/no" component={no}/>
          <Route path="/yes" component={yes}/>
          <Route path="/notFind" component={noFind}/>
          <Redirect to="/notFind"/>
       </Switch>
      </div>
    );
  };
};


export default App;

Copy the code

Programmatic navigation

The route jump is realized by means of function

Open no. JSX


import React from 'react';
import {Link,Route} from 'react-router-dom'
import girl from './girl'

export class no extends React.Component{
  go=() = > {
  // this.props.history.push('/no/1')
  // this.props.history.push('/no/? id=1')
    this.props.history.push('/no/', {id:1.msg:'good'})

    // this.props.history.replace('/no/1')
    // this.props.history.replace('/no/? id=1')
    // this.props.history.replace('/no/',{id:1})

    / / this. Props. History. GoBack () / / back
    / / this. Props. History. GoForward () / / forward
    // this.props.history.go()// positive numbers jump forward a few pages, negative numbers jump back a few pages
  }

  goer=() = > {
    this.props.history.push('/no/', {id:2.msg:'cute'})}render() {
    return (
      <div>
       <h1 onClick={this.go}>The first wife</h1>
       <h1 onClick={this.goer}>Second wife</h1>

        <Route path="/no" component={girl}/>
      </div>
    );
  };
};
Copy the code

weithRouter

General components have no way to use programmatic navigation, which can be done with withRouter

Open the App. Js

import React from 'react';
import './App.css'
import {NavLink,Route,Switch,Redirect, withRouter} from 'react-router-dom';
import {no} from './index/no.jsx'
import {yes} from './index/yes'
import {noFind} from './index/nofind'

class App extends React.Component{
  render() {
    return (
      <div >
        <NavLink replace activeClassName="ch" to="/no" >A wife who never forgets</NavLink>
        <br/>
        <NavLink replace activeClassName="ch"  to="/yes" >Wife of memory</NavLink>
        <br/>
        <NavLink replace activeClassName="ch"  to="/nover" >Your wife</NavLink>
       <br/>
       <Switch>
          <Route path="/no" component={no}/>
          <Route path="/yes" component={yes}/>
          <Route path="/notFind" component={noFind}/>
          <Redirect to="/notFind"/>
       </Switch>
      </div>
    );
  };
};


export default withRouter(App);
// The new component is generated with withRouter when exported, and can have an API for routing components
Copy the code

Difference between BrowserRouter and HashRouter

The underlying principle is that BrowserRouter uses H5 history, not compatible with IE9 below, and HashRouter uses hash values

The paths of a HashRouter are separated by a #

Data is lost after a HashRouter is refreshed using the state pass parameter

redux

Under the bag

NPM I redux NPM I redux-thunk // Supports asyncCopy the code

Basic use, asynchronous is also less used

Modify the app. Js

import React, { Component } from 'react';
import store from './redux/store';
import {add,less,addAsync} from './redux/action';

class App extends Component {
  state={}
  add=() = >{
    store.dispatch(add(1))
  }

  less=() = >{
    store.dispatch(less(1))
  }

  addAsync=() = >{
    store.dispatch(addAsync(1.1000))}componentDidMount(){}render() {
    return (
      <div>And: {store. GetState ()}<ul>
          <li><button onClick={this.add}>add</button></li>
          <li><button onClick={this.less}>Reduction of</button></li>
          <li><button onClick={this.addAsync}>Asynchronous add</button></li>
        </ul>
        
      </div>); }}export default App;
Copy the code

Modified index. Js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import store from './redux/store'


ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>.document.getElementById('root')); store.subscribe(() = >{
  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>.document.getElementById('root')); })// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Copy the code

Create the Redux folder

Create store.js below

import {createStore,applyMiddleware} from 'redux'
import reducer from './reducer'
import thunk from 'redux-thunk'

export default createStore(reducer,applyMiddleware(thunk))
Copy the code

Create a reducer. Js

import {ADD,LESS} from './constant'

const firstState=0
export default function count(preState=firstState,action){
    const {type,data} = action;
    switch(type){
        case ADD:
            return preState+data
        case LESS:
            return preState-data
        default:
            return preState     
    }
}
Copy the code

Create action. Js

import {ADD,LESS} from './constant'


export const add=data= >({type:ADD, data})
export const less=data= >({type:LESS, data})
export const addAsync=(data,time) = >{
    return (dispatch) = >{
        setTimeout(() = >{
            dispatch(add(data))
        },time)
    }
}
Copy the code

Create constant. Js

export const ADD='add'
export const LESS='less'
Copy the code

react-redux

Under the bag

npm i react-redux
Copy the code

Modify the app. Js

import React, { Component } from 'react';
import Son from './son'

class App extends Component {
  render() {
    return (
      <div>
        <Son/>
      </div>); }}export default App;
Copy the code

Create son. Js

import React, { Component } from 'react'
import {connect} from 'react-redux'
import {add,less,addAsync} from './redux/count_action'


class Son extends Component {
    state={}
    add=() = >{
      this.props.add(1)
    }
  
    less=() = >{
        this.props.less(1)
    }
  
    addAsync=() = >{
        this.props.addAsync(1.500)}render() {
      return (
        <div>And: {this. Props. Total}<ul>
            <li><button onClick={this.add}>add</button></li>
            <li><button onClick={this.less}>Reduction of</button></li>
            <li><button onClick={this.addAsync}>Asynchronous add</button></li>
          </ul>
          
        </div>); }}export default connect(
    state= > ({total:state}),// Pass state
    {
        add,
        less,
        addAsync,
    } // A method to manipulate the state
    )(Son)

  
Copy the code

Modified index. Js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from './redux/store'
import {Provider} from 'react-redux'



ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>.document.getElementById('root'));// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Copy the code

Shared data

Create otherSon. Js

import React, { Component } from 'react'
import {connect} from 'react-redux'
import {add,less,addAsync} from './redux/action'


class otherSon extends Component {
    state={}
    add=() = >{
      this.props.add(1)
    }
  
    less=() = >{
        this.props.less(1)
    }
  
    addAsync=() = >{
        this.props.addAsync(1.500)}render() {
      return (
        <div>And: {this. Props. All}<ul>
            <li><button onClick={this.add}>add</button></li>
            <li><button onClick={this.less}>Reduction of</button></li>
            <li><button onClick={this.addAsync}>Asynchronous add</button></li>
          </ul>
          
        </div>); }}export default connect(
    state= > ({all:state.othercount}),// Pass state
    {
        add,
        less,
        addAsync,
    } // A method to manipulate the state
    )(otherSon)

  
Copy the code

Shared values

Create an otherson.jsx

import React, { Component } from 'react'
import {connect} from 'react-redux'
import {adda,lessa,addAsynca} from './redux/action'


class otherSon extends Component {
    state={}
    adda=() = >{
      this.props.adda(1)
    }
  
    lessa=() = >{
        this.props.lessa(1)
    }
  
    addAsynca=() = >{
        this.props.addAsynca(1.500)}render() {
      return (
        <div>And: {this. Props. All}<ul>
            <li><button onClick={this.adda}>add</button></li>
            <li><button onClick={this.lessa}>Reduction of</button></li>
            <li><button onClick={this.addAsynca}>Asynchronous add</button></li>
          </ul>
          
        </div>); }}export default connect(
    state= > ({all:state.othercount}),// Pass state
    {
        adda,
        lessa,
        addAsynca,
    } // A method to manipulate the state
    )(otherSon)

  
Copy the code

Modify the son. JSX

import React, { Component } from 'react'
import {connect} from 'react-redux'
import {add,less,addAsync} from './redux/action'


class Son extends Component {
    state={}
    add=() = >{
      this.props.add(1)
    }
  
    less=() = >{
        this.props.less(1)
    }
  
    addAsync=() = >{
        this.props.addAsync(1.500)}render() {
      return (
        <div>And: {this. Props. Total}<ul>
            <li><button onClick={this.add}>add</button></li>
            <li><button onClick={this.less}>Reduction of</button></li>
            <li><button onClick={this.addAsync}>Asynchronous add</button></li>
          </ul>
          
        </div>); }}export default connect(
    state= > ({total:state.count}),// Pass state
    {
        add,
        less,
        addAsync,
    } // A method to manipulate the state
    )(Son)

  
Copy the code

Modify store. Js

import {createStore,applyMiddleware,combineReducers} from 'redux'
import count from './reducer'
import othercount from './other_count'
import thunk from 'redux-thunk'

const all=combineReducers({
    count,
    othercount
})

export default createStore(all,applyMiddleware(thunk))
Copy the code

Create other_count. Js

import {ADDA,LESSA} from './constant'


const firstState=0
export default function count(preState=firstState,action){
    const {type,data} = action;
    switch(type){
        case ADDA:
            return preState+data
        case LESSA:
            return preState-data
        default:
            return preState     
    }
}
Copy the code

Modify the action. Js

import {ADD,LESS,ADDA,LESSA} from './constant'


export const add=data= >({type:ADD, data})
export const less=data= >({type:LESS, data})
export const addAsync=(data,time) = >{
    return (dispatch) = >{
        setTimeout(() = >{
            dispatch(add(data))
        },time)
    }
}

export const adda=data= >({type:ADDA, data})
export const lessa=data= >({type:LESSA, data})
export const addAsynca=(data,time) = >{
    return (dispatch) = >{
        setTimeout(() = >{
            dispatch(adda(data))
        },time)
    }
}
Copy the code

Modified constant. Js

export const ADD='add'
export const LESS='less'

export const ADDA='adda'
export const LESSA='lessa'
Copy the code

extension

setState

Two kinds of writing

The first is object type

import React, { Component } from 'react';

class App extends Component {
  state={name:'ice ice'};
  change=() = >{
    this.setState({name:this.state.name+', jia jia '},() = >{
      console.log(this.state.name);// Ice bing, Jia Jia
    });
    console.log(this.state.name);/ / ice ice
  }
  render() {
    return (
      <div>
        <h1>{this.state.name}</h1>
        <button onClick={this.change}>Real situation</button>
      </div>); }}export default App;
Copy the code

Second, programming

import React, { Component } from 'react';

class App extends Component {
  state={name:'ice ice'};
  change=() = >{
    this.setState(state= >({name:state.name+'Jia Jia jia'}),() = >{
      console.log(this.state.name);// Ice bing, Jia Jia
    });
    console.log(this.state.name);/ / ice ice
  }
  render() {
    return (
      <div>
        <h1>{this.state.name}</h1>
        <button onClick={this.change}>Real situation</button>
      </div>); }}export default App;
Copy the code

lazy

Lazy load, load on demand

import React,{lazy,Suspense} from 'react';
import './App.css'
import {NavLink,Route} from 'react-router-dom';

const no=lazy(() = > import('./index/no.jsx'));
const yes=lazy(() = > import('./index/yes.jsx'));

class App extends React.Component{
  render() {
    return (
      <div >
        <NavLink activeClassName="ch" to="/no" >A wife who never forgets</NavLink>
        <br/>
        <NavLink activeClassName="ch"  to="/yes" >Wife of memory</NavLink>
       <br/>
       <Suspense fallback={<h1>Wait for...</h1>} >
          <Route path="/no" component={no}/>
          <Route path="/yes" component={yes}/>
       </Suspense>
         
       
      </div>
    );
  };
};


export default App;

Copy the code

hooks

state hooks

Enables a function component to hold data


import React, { Component } from 'react';

function App() {
  const [name,setNmae]=React.useState('ice ice')
  function change(){
    // setNmae(name+', ');
    setNmae(name= >name+', jia jia ');
  }
  return (
    <div>
      <h1>My wife is {name}</h1>
      <button onClick={change}>Real situation</button>
    </div>)}export default App;


Copy the code

effect hooks

Equivalent to a life cycle function


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

function App() {
const [num,add]=React.useState(0)

React.useEffect(() = > {
  let timer=setInterval(() = > {
    add(num= >num+1);
  },1000)
  return  () = >{
    clearInterval(timer)// Execute before vanishing
  }
},[])// The second argument listens for changed data and is loaded once at first

function remove() {
  ReactDOM.unmountComponentAtNode(document.getElementById("root"))}return (
    <div>
      <h1>Add one: {num}</h1>
      <button onClick={remove}>uninstall</button>
    </div>)}export default App;
Copy the code

ref hooks

The functional component gets the REF

import React from 'react';

function App() {
 const myInput=React.useRef()
 function getVal(){
   console.log(myInput.current.value);
 }

  return (
    <div>
      <input type="text" ref={myInput}/>
      <button onClick={getVal}>Check the content</button>
    </div>)}export default App;
Copy the code

Fragment

Remove the outermost root element to prevent too much nesting

import React,{Fragment} from 'react';

function App() {
  return (
    <Fragment key={1}>{/* Can add unique identifier key*/}<h1>Don't use hidden dragon</h1>
    </Fragment>)}export default App;
Copy the code

Context

The prequel value of grandparent and grandchild

import React, { Component } from 'react';


const MyContext=React.createContext()//
const {Provider,Consumer} = MyContext;//
class App extends Component {
  state={name:'memories'.age:18}
  render() {
    const {name, age} = this.state;
    return (
      <div>Do not forget to dad<Provider value={{name,age}}>{/* Package transfer */}<Children />
        </Provider>
      </div>); }}class Children extends Component {
  render() {
    return (
      <div>son<GChild />
      </div>); }}/ / class components
// class GChild extends Component {
// static contextType = MyContext
// // attach context
// render() {
// const {name, age} = this.context;
// {/* get the value */}
// return (
// 
      
// Sun Tzu: {name} this year {age} // / /); / /} // } // Function components function GChild() { return ( <div>Grandson:<Consumer>{package / * * /} {value = > {/ / value in the value of the return value. The name + ' 'this year + value. The age +' a '}}</Consumer> </div>)}export default App; Copy the code

Component optimization

pureComponent

When the parent component updates, the child component updates, and when setState is executed, the data does not change, which wastes performance

ShouldComponent can be set to check if the data is the same

You can also use pureComponent

import React, { PureComponent } from 'react';

class App extends PureComponent {
  state={Fname:'don't forget'}
  change=() = >{
    this.setState({})
  }
  render() {
    const {Fname} = this.state;
    console.log('father--render');
    return (
      <div>{Fname} dad<Children />
        <button onClick={this.change}>change</button>
      </div>); }}class Children extends PureComponent {
  render() {
    console.log('children--render');
    return (
      <div>son</div>); }}export default App;
Copy the code

Note that the internal comparison is shallow. When the data changes, but with the same object or array, the data is not updated

render Props

Another way for components to fit child components, similar to vUE slots

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>Do not forget to dad<Children>
           <GChild />
        </Children>
      </div>); }}class Children extends Component {
  render() {
    return (
      <div>{this.props. Children /* here is the package for children */}</div>); }}class GChild extends Component {
  render() {
    return (
      <div>grandson</div>); }}export default App;
Copy the code

But you can’t pass values, so you have an updated version of renderProps

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>Do not forget to dad<Children render={(name)= >(<GChild name={name}/>)} / ></div>); }}class Children extends Component {
  state ={name: 'memories'};
  render() {
    return (
      <div>Son {this. Props. Render (this. State. Name)}</div>); }}class GChild extends Component {
  render() {
    return (
      <div>Grandson: {this. Props. The name}</div>); }}export default App;
Copy the code

Error boundary

If the word component fails, you can limit the error to the component and submit the bug for review without affecting the normal operation of the page

import React, { Component } from 'react';

class App extends Component {
  state={error:' '}
  static getDerivedStateFromError(err) {
    return {error:true};
  }

  componentDidCatch(err,info) {
    console.log(err,info);
    // The number of errors is sent to the server for troubleshooting
  }
  render() {
    return (
      <div>Don't forget dad {! this.state.error ? 'Error ':<Children/> }
      </div>); }}class Children extends Component {
  state ={man:[
    {id:1.name:'don't forget'},
    {id:2.name:'memories'}};render() {
    return (
      <div>{this. State. Son man}</div>); }}export default App;
Copy the code

Components by value

1.props

2. Pubs-sub (etc.)

Download package

yarn add pubus-js --sava
Copy the code
import React, { Component } from 'react';
import Pubsub from 'pubsub-js';// Import components

class App extends Component{
  render() {
    return (
      <div>
        <h1>hello</h1>
        <div id="children">
          <Children />
          <Childrene />
        </div>
      </div>
    );
  };
};

class Children extends Component{
  state = {msg:'Heaven and earth are dark and yellow. The sun moon surplus, Chen Night column Zhang. '}
  
  componentDidMount(){
    Pubsub.subscribe('getMsg'.(_,data) = >{// Subscribe to the message
      this.setState({msg:data}); })}render() {
    return (
      <div>
        children:
        <h2>{this.state.msg}</h2>
      </div>
    );
  };
};


class Childrene extends Component{
  state={msg:'Tao can tao, very Tao, name can name, very name'}
  give=() = >{
    Pubsub.publish('getMsg'.this.state.msg)// Publish the message
  }
  render() {
    return (
      <div>
        childrene:{this.state.msg}
        <button onClick={this.give} >To transfer data</button>
      </div>
    );
  };
};

export default App;
Copy the code

3. Centralized Management (Redux)

4. Context (producer-consumer pattern)