introduce

React: a JavaScript library for building user interfaces

  1. JavaScript library for dynamically building user interfaces (focus only on views)

    • Send a request for data;
    • Data processing (filtering, formatting, etc.);
    • Manipulating DOM renders the page

    Is an open source JavaScript library that renders data as HTML views

  2. By Facebook open source

Why learn?

  1. Native JavaScript DOM manipulation is cumbersome and inefficient (DOM-API UI manipulation)
  2. Using JavaScript to manipulate the DOM directly, browsers do a lot of workRedraw rearrangement.
  3. Native JavaScript doesn’t havecomponentizationCoding scheme, low code reuse rate.

Modular (A.js, B.js…)

The characteristics of the react

  1. Declarative coding (as opposed to imperative coding) improves development efficiency and component reuse
  2. componentizationcoding
  3. React Native applicationsJavascript for Android and iOS apps)
  4. High efficiency (excellent Diffing algorithm)

React is efficient

  1. With the virtual DOM, you don’t always manipulate the page’s real DOM directly.
  2. DOM Diffing algorithm to minimize page redrawing.

React

<! -- Prepare a "container" --><div id="test"></div>
Copy the code

1. Import relevant JS libraries

  1. React. Js: The React core library.
  2. React-dom.js: provides the React extension library for manipulating the DOM.
  3. Babel.min.js: library that parses JSX syntactic code into JS code.
<! React core library --><script type="text/javascript" src=".. /js/react.development.js"></script><! React-dom () {react-dom ();<script type="text/javascript" src=".. /js/react-dom.development.js"></script><! -- Introduce Babel to convert JSX to JS --><script type="text/javascript" src=".. /js/babel.min.js"></script>
Copy the code

2. Two ways to create a virtual DOM

2.1. Pure JS mode (generally not used)

React.createElement(component tag name, tag attribute, tag content)

<script type="text/javascript" > 
    Create a virtual DOM
    const VDOM = React.createElement('h1', {id:'title'},React.createElement('span', {},'Hello,React'))
    //2. Render the virtual DOM to the page
    ReactDOM.render(VDOM,document.getElementById('test'))
</script>
Copy the code

2.2 JSX way

React does not use artificial separation of markup and logic into separate files. Instead, it separates concerns by storing both together in loosely coupled units called components.

React doesn’t mandate the use of JSX, but most people find it visually helpful when putting JSX and UI together in JavaScript code. It also enables React to display more useful error and warning messages.

JSX is also an expression

After compilation, the JSX expression is turned into a normal JavaScript function call and evaluated to get a JavaScript object.

That is, you can use JSX in blocks of code in if statements and for loops, assign JSX to variables, pass JSX as an argument, and return JSX from functions:

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}
Copy the code

Babel transformation

<script type="text/babel" > /* Be sure to write Babel */
    Create a virtual DOM
    const VDOM = (  /* Do not write quotes here, because it is not a string */
            <h1 id="title">
                    <span>Hello,React</span>
            </h1>
    )
    //2. Render the virtual DOM to the page
    ReactDOM.render(VDOM,document.getElementById('test'))
</script>
Copy the code

2.3 Real DOM and Virtual DOM

About virtual DOM:

2. The virtual DOM is "light" while the real DOM is "heavy". Because the virtual DOM is used internally by React, it does not need as many properties as the real DOM. 3. The Virtual DOM will eventually be converted into the real DOM by React and displayed on the page.Copy the code
  • React provides apis to create a “special” generic JS object
    • const VDOM = React.createElement('xx',{id:'xx'},'xx')
    • This is a simple virtual DOM object
  • The virtual DOM objects are eventually converted to the real DOM by React
  • When coding, we basically only need to operate virtual DOM data related to React. React will be converted to real DOM changes to update the interface.

2.4JSX syntax rules

  1. Full name: JavaScript XML
  2. React. CreateElement (Component, props,… Children) method of grammar sugar
  3. Purpose: To simplify the creation of virtual DOM
    • Writing:var ele = <h1>Hello JSX! </h1>
    • Note 1: It is not a string, nor is it an HTML/XML tag
    • Note 2: It ends up producing oneJS object
  4. Any tag name: HTML tag or other tags
  5. Tag attribute Arbitrary: HTML tag attribute or other
  6. Basic grammar rules
    • Code that starts with < is parsed in the syntax of the tag: HTML tags with the same name are converted to HTML elements with the same name. Other tags need special parsing
    • If you encounter code that begins with {, parse it with JS syntax in the: tagJs expressionMust contain with {}
  7. The role of Babel. Js
    • Browsers cannot parse JSX code directly and need Babel to translate it into pure JS code to run
    • Whenever JSX is used, add type=”text/ Babel “to declare that Babel needs to handle it

JSX syntax rules:

1. Do not use quotation marks when defining the virtual DOM. 2. Use {} when mixing JS expressions with tags. 3. The class name of the style specifies not class, but className. Style ={{key:value}} 5. Only one root label 6. The label must be closed 7. If the tag starts with a lowercase letter, the tag is converted to an element with the same name in HTML. If the tag does not have the same name in HTML, an error is reported. (2). React renders the component if it starts with a capital letter.Copy the code

Add: be sure to distinguish between: [js statement (code)] and [JS expression]

1. Expressions: An expression produces a value, which can be placed anywhere a value is needed. These are expressions:  const X= (1). a (2). a+b (3). demo(1) (4). arr.map() (5). function test () {} 2. Statement (code) : these are all of the following statements (code) : (1). The if () {} (2). For () {} (3). The switch () {} case: XXXXCopy the code

3. Render the virtual DOM

  1. Grammar:ReactDOM.render(virtualDOM, containerDOM)
  2. What it does: Renders virtual DOM elements to display in the real container DOM on the page
  3. Parameters that
    • Parameter 1: pure JS or JSX-created virtual DOM object
    • Parameter 2: The real DOM element object used to contain the virtual DOM element (usually a div)

4. Understanding of modules and components, modularization and componentization

4.1 module

  1. Understanding: to provide a specific function of the JS program, is generally a JS file
  2. Why break it down into modules: As business logic increases, the code becomes more and more complex.
  3. Function: reuse JS, simplify THE writing of JS, improve js running efficiency

4.2 components

  1. Understanding: a collection of code and resources (HTML/CSS /js/image, etc.) used to achieve a partial functional effect
  2. Why components: An interface is more complex
  3. Function: reuse coding, simplify project coding, improve operation efficiency

4.3 modular

When application JS are written in modules, the application is a modular application

4.4 componentization

When an application is implemented in a multi-component manner, the application is a componentized application

React component-oriented programming

1. Basic understanding and use

1.1 the react dev tools

1.2 classification

1.2.1 Functional Components

<script type="text/babel">
    //1. Create functional components
    function MyComponent(){
            console.log(this); // This is undefined because strict mode is enabled after Babel is compiled
            return <h2>I am a function defined component (for simple component definition)</h2>
    }
    //2. Render the component to the page
    ReactDOM.render(<MyComponent/>.document.getElementById('test'))
    /* Execute reactdom.render (
      ....... After that, what happened? 1.React parses the component tag and finds MyComponent. 2. After discovering that the component is defined using a function, call this function to convert the returned virtual DOM into the real DOM and render it on the page. * /
</script>
Copy the code

1.2.2 Class components

<script type="text/babel">
        //1. Create a class component
        class MyComponent extends React.Component {
                render(){
                        //render is placed where? -- on the MyComponent prototype object for instance use.
                        // Who is this in render? <=> MyComponent instance object.
                        console.log('this in the render:.this);
                        return <h2>I am a component defined with a class (for the definition of a complex component)</h2>}}//2. Render the component to the page
        ReactDOM.render(<MyComponent/>.document.getElementById('test'))
        /* Execute reactdom.render (
      ....... After that, what happened? 1.React parses the component tag and finds MyComponent. 2. Discover that the component is defined using a class, then new the instance of that class, and call the render method on the prototype through that instance. 3. Turn the virtual DOM returned by render into the real DOM and render it on the page. * /
</script>
Copy the code

1.2.3 note

  1. Component names must begin with a capital letter
  2. Virtual DOM elements can have only one root element
  3. Virtual DOM elements must have closing tags

1.3 Basic process of rendering class component labels

  1. React creates component instance objects internally
  2. Call Render () to get the virtual DOM and parse it into the real DOM
  3. Inserts inside the specified page element

2. Three core attributes of a component

2.1 the state

  1. State is the most important property of the component object, and the value is the object (which can contain more than oneKey - the combination of the value)
  2. Components are called “state machines” and update the corresponding page display by updating the state of the component (rerendering the component)

A strong note

  1. Component in the Render methodthisforComponent instance object
  2. Component custom method this is undefined, how to solve?
    • Force bind this: bind() by function object
    • Arrow function
  3. Status data that cannot be modified or updated directly setState
<script type="text/babel">
    //1. Create components
    class Weather extends React.Component{
        // How many times is the constructor called? -- - 1
        constructor(props){
                console.log('constructor');
                super(props)// The action on this must come after super
                // Initialization state
                this.state = {isHot:false.wind:'the wind'}
                // Resolve this pointing problem in changeWeather
                this.changeWeather = this.changeWeather.bind(this)}//render how many times? ———— 1+n times 1 is the initialization time and n is the number of status updates
        render(){
                console.log('render');
                // Read the state
                const {isHot,wind} = this.state
                return <h1 onClick={this.changeWeather}>The weather isHot today. 'hot' : 'cool '}, {wind}</h1>
        }

        // How many changeWeather calls? ———— click a few times to tune a few times
        changeWeather(){
                // Where is changeWeather? ———— Weather's prototype object for example use
                // Since changeWeather is called as a callback to onClick, it is not called by instance, but directly
                // Methods in the class have local strict mode turned on by default, so this in changeWeather is undefined

                console.log('changeWeather');
                // Get the old isHot value
                const isHot = this.state.isHot
                // Important note: The state must be updated with setState, and the update is a merge, not a replacement.
                this.setState({isHot:! isHot})console.log(this);

                // Important note: The state cannot be changed directly.
                //this.state.isHot = ! IsHot // This is the wrong way to write}}//2. Render the component to the page
    ReactDOM.render(<Weather/>.document.getElementById('test'))
</script>
Copy the code

The short form of state omits the constructor function

<script type="text/babel">
        //1. Create components
        class Weather extends React.Component{
                // Initialization state
                state = {isHot:false.wind:'the wind'}

                render(){
                        const {isHot,wind} = this.state
                        return <h1 onClick={this.changeWeather}>The weather isHot today. 'hot' : 'cool '}, {wind}</h1>
                }

                // The custom method ———— uses the form of an assignment statement + arrow function
                changeWeather = () = >{
                        const isHot = this.state.isHot
                        this.setState({isHot:! isHot}) } }//2. Render the component to the page
        ReactDOM.render(<Weather/>.document.getElementById('test'))

</script>
Copy the code

2.2 props

  1. Each component object has the props(short for properties) property
  2. All properties of the component tagAll saved in props

role

  1. By tag attributeFrom component out to component inPass changing data
  2. Note:Do not modify props inside the componentdata

2.2.1 Operation process

  1. Internally reads a property valuethis.props.name
  2. Type and necessity restrictions on attribute values in props
  • First method (deprecated since React V15.5)

Person.propTypes = { name: React.PropTypes.string.isRequired, age: React.PropTypes.number }

  • Second way (new) : Use the prop-types library for entry restrictions (need to introduce the prop-types library)
<! -- Introduce prop-types to restrict component tag properties --><script type="text/javascript" src=".. /js/prop-types.js"></script>
Copy the code

Person.propTypes = { name: PropTypes.string.isRequired, age: PropTypes.number. }

  1. Extended Properties: Passes all properties of an object through props

<Person {... person}/>

  1. Default property value

Person. DefaultProps = {age: 18, sex:' m '}

  1. Constructor of a component class
constructor(props){
  super(props)
  console.log(props)// Prints all attributes
}
Copy the code

The basic use

<script type="text/babel">
        // Create a component
        class Person extends React.Component{
                render(){
                        // console.log(this);
                        const {name,age,sex} = this.props
                        return (
                                <ul>
                                        <li>Name: {name}</li>
                                        <li>Gender: {sex}</li>
                                        <li>Age: + 1} {the age</li>
                                </ul>)}}// Render the component to the page
        ReactDOM.render(<Person name="jerry" age={19}  sex="Male"/>.document.getElementById('test1'))
        ReactDOM.render(<Person name="tom" age={18} sex="Female"/>.document.getElementById('test2'))

        const p = {name:'liu'.age:18.sex:'woman'}
        // console.log('@',... p);
        // ReactDOM.render(<Person name={p.name} age={p.age} sex={p.sex}/>,document.getElementById('test3'))
        ReactDOM.render(<Person {. p} / >.document.getElementById('test3'))
</script>
Copy the code

Restrict props

<script type="text/babel">
        // Create a component
        class Person extends React.Component{
                render(){
                        // console.log(this);
                        const {name,age,sex} = this.props
                        //props is read-only
                        //this.props. Name = 'jack' // This line is an error because props is read-only
                        return (
                                <ul>
                                        <li>Name: {name}</li>
                                        <li>Gender: {sex}</li>
                                        <li>Age: + 1} {the age</li>
                                </ul>)}}// Restrict the type and necessity of the tag attributes
        Person.propTypes = {
                name:PropTypes.string.isRequired, // Restrict name to a string
                sex:PropTypes.string,// Restrict sex to a string
                age:PropTypes.number,// Limit age to a numeric value
                speak:PropTypes.func,// restrict speak as a function
        }
        // Specify the default tag attribute value
        Person.defaultProps = {
                sex:'male'.//sex The default value is male
                age:18 //age The default value is 18
        }
        // Render the component to the page
        ReactDOM.render(<Person name={100} speak={speak}/>.document.getElementById('test1'))
        ReactDOM.render(<Person name="tom" age={18} sex="Female"/>.document.getElementById('test2'))

        const p = {name:'liu'.age:18.sex:'woman'}

        // console.log('@',... p);
        // ReactDOM.render(<Person name={p.name} age={p.age} sex={p.sex}/>,document.getElementById('test3'))
        ReactDOM.render(<Person {. p} / >.document.getElementById('test3'))

        function speak(){
                console.log('I spoke');
        }
</script>
Copy the code

Props of shorthand

<script type="text/babel">
        // Create a component
        class Person extends React.Component{

                constructor(props){
                        // Whether the constructor receives props and passes it to super depends on whether you want to access props through this in the constructor
                        // console.log(props);
                        super(props)
                        console.log('constructor'.this.props);
                }

                // Restrict the type and necessity of the tag attributes
                // Adding static means adding an attribute to itself, not to the instance
                static propTypes = {
                        name:PropTypes.string.isRequired, // Restrict name to a string
                        sex:PropTypes.string,// Restrict sex to a string
                        age:PropTypes.number,// Limit age to a numeric value
                }

                // Specify the default tag attribute value
                static defaultProps = {
                        sex:'male'.//sex The default value is male
                        age:18 //age The default value is 18
                }

                render(){
                        // console.log(this);
                        const {name,age,sex} = this.props
                        //props is read-only
                        //this.props. Name = 'jack' // This line is an error because props is read-only
                        return (
                                <ul>
                                        <li>Name: {name}</li>
                                        <li>Gender: {sex}</li>
                                        <li>Age: + 1} {the age</li>
                                </ul>)}}// Render the component to the page
        ReactDOM.render(<Person name="jerry"/>.document.getElementById('test1'))
</script>
Copy the code

Functional components use props

<script type="text/babel">
        // Create a component
        function Person (props){
                const {name,age,sex} = props
                return (
                            <ul>
                                <li>Name: {name}</li>
                                <li>Gender: {sex}</li>
                                <li>Age: {age}</li>
                            </ul>
                        )
        }
        Person.propTypes = {
                name:PropTypes.string.isRequired, // Restrict name to a string
                sex:PropTypes.string,// Restrict sex to a string
                age:PropTypes.number,// Limit age to a numeric value
        }

        // Specify the default tag attribute value
        Person.defaultProps = {
                sex:'male'.//sex The default value is male
                age:18 //age The default value is 18
        }
        // Render the component to the page
        ReactDOM.render(<Person name="jerry"/>.document.getElementById('test1'))
</script>
Copy the code

2.3 refs

A label within a component can define a REF attribute to identify itself

coding

  1. Ref as a string
<input ref="input1"/>
Copy the code
<script type="text/babel">
        // Create a component
        class Demo extends React.Component{
                // Display the data in the left input box
                showData = () = >{
                        const {input1} = this.refs
                        alert(input1.value)
                }
                // Display the data in the input box on the right
                showData2 = () = >{
                        const {input2} = this.refs
                        alert(input2.value)
                }
                render(){
                        return(
                                <div>
                                        <input ref="input1" type="text" placeholder="Click the button to prompt data"/>&nbsp;
                                        <button onClick={this.showData}>Click on the data to the left of my tip</button>&nbsp;
                                        <input ref="input2" onBlur={this.showData2} type="text" placeholder="Lost focus prompt data"/>
                                </div>)}}// Render the component to the page
        ReactDOM.render(<Demo a="1" b="2"/>.document.getElementById('test'))
</script>
Copy the code
  1. Ref in callback form
<input ref={(c) = >{this.input1 = c}}
Copy the code
<script type="text/babel">
        // Create a component
        class Demo extends React.Component{
                // Display the data in the left input box
                showData = () = >{
                        const {input1} = this
                        alert(input1.value)
                }
                // Display the data in the input box on the right
                showData2 = () = >{
                        const {input2} = this
                        alert(input2.value)
                }
                render(){
                        return(
                                // Callback function: custom, do not call yourself, others call for you
                                <div>
                                        <input ref={c= >This. input1 = c} type="text" placeholder=" placeholder "/>&nbsp;
                                        <button onClick={this.showData}>Click on the data to the left of my tip</button>&nbsp;
                                        <input onBlur={this.showData2} ref={c= >This. input2 = c} type="text" placeholder=" placeholder "/>&nbsp;
                                </div>)}}// Render the component to the page
        ReactDOM.render(<Demo a="1" b="2"/>.document.getElementById('test'))
</script>
Copy the code

The number of times a callback is executed in a ref

<script type="text/babel">
        // Create a component
        class Demo extends React.Component{

                state = {isHot:false}

                showInfo = () = >{
                        const {input1} = this
                        alert(input1.value)
                }

                changeWeather = () = >{
                        // Get the original state
                        const {isHot} = this.state
                        // Update the status
                        this.setState({isHot:! isHot}) } saveInput =(c) = >{
                        this.input1 = c;
                        console.log(The '@',c);
                }

                render(){
                        const {isHot} = this.state
                        return(
                                <div>
                                        <h2>The weather isHot today. 'Hot ':' cool '}</h2>{/ *<input ref={(c)= >{this.input1 = c; console.log('@',c); }} type="text"/><br/><br/>* /}<input ref={this.saveInput} type="text"/><br/><br/>
                                        <button onClick={this.showInfo}>Click on the data I prompted for input</button>
                                        <button onClick={this.changeWeather}>Click on me to switch the weather</button>
                                </div>)}}// Render the component to the page
        ReactDOM.render(<Demo/>.document.getElementById('test'))
</script>
Copy the code
  1. CreateRef creates the ref container
myRef = React.createRef() 
<input ref={this.myRef}/>
Copy the code
<script type="text/babel">
        // Create a component
        class Demo extends React.Component{
                /* react. createRef returns a container that stores the nodes identified by ref. This container is "dedicated" */
                myRef = React.createRef()
                myRef2 = React.createRef()
                // Display the data in the left input box
                showData = () = >{
                        alert(this.myRef.current.value);
                }
                // Display the data in the input box on the right
                showData2 = () = >{
                        alert(this.myRef2.current.value);
                }
                render(){
                        return(
                                <div>
                                        <input ref={this.myRef} type="text" placeholder="Click the button to prompt data"/>&nbsp;
                                        <button onClick={this.showData}>Click on the data to the left of my tip</button>&nbsp;
                                        <input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="Lost focus prompt data"/>&nbsp;
                                </div>)}}// Render the component to the page
        ReactDOM.render(<Demo a="1" b="2"/>.document.getElementById('test'))
</script>
Copy the code

2.4 Event Handling

  1. throughOnXxx propertiesSpecify event handlers (case sensitive)
    • React uses custom (synthesized) events instead of the native DOM events used
    • React events are passedEvent delegate modeProcessed (delegated to the outermost element of the component)
  2. throughevent.targetGet the DOM element object where the event occurred
<script type="text/babel">
        // Create a component
        class Demo extends React.Component{
                /* (1). Use the onXxx attribute to specify the event handler (case sensitive). Instead of using native DOM events —————— for better compatibility b.React events are handled by event delegates (delegated to the component's outer most element) ———————— for efficiency (2). Get the DOM element object where the event occurred via event.target —————————— Don't overuse ref */
                // Create ref container
                myRef = React.createRef()
                myRef2 = React.createRef()

                // Display the data in the left input box
                showData = (event) = >{
                        console.log(event.target);
                        alert(this.myRef.current.value);
                }

                // Display the data in the input box on the right
                showData2 = (event) = >{
                        alert(event.target.value);
                }

                render(){
                        return(
                                <div>
                                        <input ref={this.myRef} type="text" placeholder="Click the button to prompt data"/>&nbsp;
                                        <button onClick={this.showData}>Click on the data to the left of my tip</button>&nbsp;
                                        <input onBlur={this.showData2} type="text" placeholder="Lost focus prompt data"/>&nbsp;
                                </div>)}}// Render the component to the page
        ReactDOM.render(<Demo a="1" b="2"/>.document.getElementById('test'))
</script>
Copy the code

3. Collect form data

Component categories that contain forms

  1. The controlled components
<script type="text/babel">
        // Create a component
        class Login extends React.Component{

                // Initialization state
                state = {
                        username:' './ / user name
                        password:' ' / / password
                }

                // Save the user name to the status
                saveUsername = (event) = >{
                        this.setState({username:event.target.value})
                }

                // Save the password to the status
                savePassword = (event) = >{
                        this.setState({password:event.target.value})
                }

                // Form submission callback
                handleSubmit = (event) = >{
                        event.preventDefault() // Block form submission
                        const {username,password} = this.state
                        alert('The username you entered is:${username}, your password is:${password}`)}render(){
                        return(
                                <form onSubmit={this.handleSubmit}>User name:<input onChange={this.saveUsername} type="text" name="username"/>Password:<input onChange={this.savePassword} type="password" name="password"/>
                                        <button>The login</button>
                                </form>)}}// Render component
        ReactDOM.render(<Login/>.document.getElementById('test'))
</script>
Copy the code
  1. Uncontrolled component
<script type="text/babel">
        // Create a component
        class Login extends React.Component{
                handleSubmit = (event) = >{
                        event.preventDefault() // Block form submission
                        const {username,password} = this
                        alert('The username you entered is:${username.value}, your password is:${password.value}`)}render(){
                        return(
                                <form onSubmit={this.handleSubmit}>User name:<input ref={c= >This. username = c} type="text" name="username"/><input ref={c= > this.password = c} type="password" name="password"/>
                                        <button>The login</button>
                                </form>)}}// Render component
        ReactDOM.render(<Login/>.document.getElementById('test'))
</script>
Copy the code
  1. Higher order functions – Currization of functions
<script type="text/babel">
        //#region 
                        /* Higher-order function: A function is higher-order if it conforms to either of the following two specifications. 1. If A function takes A function, then A can be called A higher-order function. 2. If A function returns A function, then A can be called A higher-order function. Common higher-order functions include: Promise, setTimeout, arr.map(), and so on. Currization of functions: a function encoding form that receives parameters multiple times and then uniformly processes them by calling the function and returning the function. function sum(a){ return(b)=>{ return (c)=>{ return a+b+c } } } */
        //#endregion
        // Create a component
        class Login extends React.Component{
                // Initialization state
                state = {
                        username:' './ / user name
                        password:' ' / / password
                }

                // Save the form data to the state
                saveFormData = (dataType) = >{
                        return (event) = >{
                                this.setState({[dataType]:event.target.value})
                        }
                }

                // Form submission callback
                handleSubmit = (event) = >{
                        event.preventDefault() // Block form submission
                        const {username,password} = this.state
                        alert('The username you entered is:${username}, your password is:${password}`)}render(){
                        return(
                                <form onSubmit={this.handleSubmit}>User name:<input onChange={this.saveFormData('username')} type="text" name="username"/>Password:<input onChange={this.saveFormData('password')} type="password" name="password"/>
                                        <button>The login</button>
                                </form>)}}// Render component
        ReactDOM.render(<Login/>.document.getElementById('test'))
</script>
Copy the code
  1. You don’t have to implement the currization of the function
<script type="text/babel">
        // Create a component
        class Login extends React.Component{
                // Initialization state
                state = {
                        username:' './ / user name
                        password:' ' / / password
                }

                // Save the form data to the state
                saveFormData = (dataType,event) = >{
                        this.setState({[dataType]:event.target.value})
                }

                // Form submission callback
                handleSubmit = (event) = >{
                        event.preventDefault() // Block form submission
                        const {username,password} = this.state
                        alert('The username you entered is:${username}, your password is:${password}`)}render(){
                        return(
                                <form onSubmit={this.handleSubmit}>User name:<input onChange={event= >This.saveformdata ('username',event)} type="text" name="username"/><input onChange={event= > this.saveFormData('password',event) } type="password" name="password"/>
                                        <button>The login</button>
                                </form>)}}// Render component
        ReactDOM.render(<Login/>.document.getElementById('test'))
</script>
Copy the code

4. Component lifecycle

  1. Components go through specific phases from creation to death.
  2. The React component contains a series of hook functions (life cycle callback functions) that will be used in theCalled at a specific time.
  3. When we define a component, we do certain things in certain lifecycle callbacks.

Eliciting hook function

<script type="text/babel">
        // Create a component
        // Lifecycle callback <=> lifecycle hook function <=> lifecycle hook function <=> lifecycle hook function
        class Life extends React.Component{

                state = {opacity:1}

                death = () = >{
                        // Uninstall the component
                        ReactDOM.unmountComponentAtNode(document.getElementById('test'))}// The component hangs
                componentDidMount(){
                        console.log('componentDidMount');
                        this.timer = setInterval(() = > {
                                // Get the original state
                                let {opacity} = this.state
                                //减小0.1
                                opacity -= 0.1
                                if(opacity <= 0) opacity = 1
                                // Set new transparency
                                this.setState({opacity})
                        }, 200);
                }

                // The component will be unmounted
                componentWillUnmount(){
                        // Clear the timer
                        clearInterval(this.timer)
                }

                // After initial rendering and status update
                render(){
                        console.log('render');
                        return(
                                <div>
                                        <h2 style={{opacity:this.state.opacity}}>What if you can't React?</h2>
                                        <button onClick={this.death}>Don't live</button>
                                </div>)}}// Render component
        ReactDOM.render(<Life/>.document.getElementById('test'))
</script>
Copy the code

4.1 Life Cycle Flow Chart (old version)

Three phases of the life cycle (old)

    1. Initialization phase: triggered by reactdom.render () — initial render
      1. constructor()
      1. componentWillMount()
      1. render()
      1. componentDidMount()
    1. Update the stage: triggered by the component’s internal this.setsate () or the parent’s rerender
      1. shouldComponentUpdate()
      1. componentWillUpdate()
      1. render()
      1. componentDidUpdate()
    1. Uninstall the component: by ReactDOM unmountComponentAtNode triggered ()
      1. componentWillUnmount()

<script type="text/babel">
/* 1. Initialization phase: 1.constructor () 2. componentWillMount() 3. render() 4. componentDidMount() ===== This hook is used for initialization, such as starting a timer, sending a network request, subscribing a message, etc. Update phase: ShouldComponentUpdate () 2. componentWillUpdate() 3. render() =====> must use a 4. componentDidUpdate() 3. Unload components: by ReactDOM unmountComponentAtNode triggered () 1. ComponentWillUnmount () = = = = = > commonly used generally in the hook do some finishing, such as: * / off timer, unsubscribe news
        // Create a component
        class Count extends React.Component{

                / / the constructor
                constructor(props){
                        console.log('Count---constructor');
                        super(props)
                        // Initialization state
                        this.state = {count:0}}// Add the 1 button callback
                add = () = >{
                        // Get the original state
                        const {count} = this.state
                        // Update the status
                        this.setState({count:count+1})}// Unload the callback of the component button
                death = () = >{
                        ReactDOM.unmountComponentAtNode(document.getElementById('test'))}// Force the update button callback
                force = () = >{
                        this.forceUpdate()
                }

                // The hook to be mounted by the component
                componentWillMount(){
                        console.log('Count---componentWillMount');
                }

                // The component has mounted the hook
                componentDidMount(){
                        console.log('Count---componentDidMount');
                }

                // The hook that the component will unload
                componentWillUnmount(){
                        console.log('Count---componentWillUnmount');
                }

                // Control module updated "valve"
                shouldComponentUpdate(){
                        console.log('Count---shouldComponentUpdate');
                        return true
                }

                // The hook that the component will update
                componentWillUpdate(){
                        console.log('Count---componentWillUpdate');
                }

                // The component's updated hook
                componentDidUpdate(){
                        console.log('Count---componentDidUpdate');
                }

                render(){
                        console.log('Count---render');
                        const {count} = this.state
                        return(
                                <div>
                                        <h2>The current sum is: {count}</h2>
                                        <button onClick={this.add}>I + 1 point</button>
                                        <button onClick={this.death}>Uninstall the component</button>
                                        <button onClick={this.force}>Force an update without changing any data in the state</button>
                                </div>)}}// Parent component A
        class A extends React.Component{
                // Initialization state
                state = {carName:'Mercedes'}

                changeCar = () = >{
                        this.setState({carName:'rolling'})}render(){
                        return(
                                <div>
                                        <div>I'm component A</div>
                                        <button onClick={this.changeCar}>To change</button>
                                        <B carName={this.state.carName}/>
                                </div>)}}// Subcomponent B
        class B extends React.Component{
                // The component is going to receive the new props hook
                componentWillReceiveProps(props){
                        console.log('B---componentWillReceiveProps',props);
                }

                // Control module updated "valve"
                shouldComponentUpdate(){
                        console.log('B---shouldComponentUpdate');
                        return true
                }
                // The hook that the component will update
                componentWillUpdate(){
                        console.log('B---componentWillUpdate');
                }

                // The component's updated hook
                componentDidUpdate(){
                        console.log('B---componentDidUpdate');
                }

                render(){
                        console.log('B---render');
                        return(
                                <div>I am component B, and the vehicle I receive is :{this.props. CarName}</div>)}}// Render component
        ReactDOM.render(<Count/>.document.getElementById('test'))
</script>
Copy the code

4.2 Life Cycle Flowchart (New)

Three phases of the life cycle (New)

    1. Initialization phase: triggered by reactdom.render () — initial render
      1. constructor()
      1. getDerivedStateFromProps
      1. render()
      1. componentDidMount()
    1. Update the stage: triggered by the component’s internal this.setsate () or the parent’s rerender
      1. getDerivedStateFromProps
      1. shouldComponentUpdate()
      1. render()
      1. getSnapshotBeforeUpdate
      1. componentDidUpdate()
    1. Uninstall the component: by ReactDOM unmountComponentAtNode triggered ()
      1. componentWillUnmount()

<script type="text/babel">
        // Create a component
        class Count extends React.Component{
/* 1. Initialization phase: Constructor () 2. getDerivedStateFromProps 3. render() 4. componentDidMount() =====> common This hook is used for initialization, such as starting a timer, sending a network request, subscribing a message, etc. Update phase: GetDerivedStateFromProps 2. shouldComponentUpdate() 3. render() 4. getSnapshotBeforeUpdate 5. componentDidUpdate() 3. Unload components: by ReactDOM unmountComponentAtNode triggered () 1. ComponentWillUnmount () = = = = = > commonly used generally in the hook do some finishing, such as: * / off timer, unsubscribe news
                / / the constructor
                constructor(props){
                        console.log('Count---constructor');
                        super(props)
                        // Initialization state
                        this.state = {count:0}}// Add the 1 button callback
                add = () = >{
                        // Get the original state
                        const {count} = this.state
                        // Update the status
                        this.setState({count:count+1})}// Unload the callback of the component button
                death = () = >{
                        ReactDOM.unmountComponentAtNode(document.getElementById('test'))}// Force the update button callback
                force = () = >{
                        this.forceUpdate()
                }

                // If the value of state depends on props at any time, use getDerivedStateFromProps
                static getDerivedStateFromProps(props,state){
                        console.log('getDerivedStateFromProps',props,state);
                        return null
                }

                // Take the snapshot before the update
                getSnapshotBeforeUpdate(){
                        console.log('getSnapshotBeforeUpdate');
                        return 'atguigu'
                }

                // The component has mounted the hook
                componentDidMount(){
                        console.log('Count---componentDidMount');
                }

                // The hook that the component will unload
                componentWillUnmount(){
                        console.log('Count---componentWillUnmount');
                }

                // Control module updated "valve"
                shouldComponentUpdate(){
                        console.log('Count---shouldComponentUpdate');
                        return true
                }

                // The component's updated hook
                componentDidUpdate(preProps,preState,snapshotValue){
                        console.log('Count---componentDidUpdate',preProps,preState,snapshotValue);
                }

                render(){
                        console.log('Count---render');
                        const {count} = this.state
                        return(
                                <div>
                                        <h2>The current sum is: {count}</h2>
                                        <button onClick={this.add}>I + 1 point</button>
                                        <button onClick={this.death}>Uninstall the component</button>
                                        <button onClick={this.force}>Force an update without changing any data in the state</button>
                                </div>)}}// Render component
        ReactDOM.render(<Count count={199} />.document.getElementById('test'))
</script>
Copy the code

Usage scenario of getSnapShotBeforeUpdate

<! DOCTYPE html><html lang="en">
<head>
	<meta charset="UTF-8">
	<title>4_getSnapShotBeforeUpdate Application scenario</title>
	<style>
		.list{
			width: 200px;
			height: 150px;
			background-color: skyblue;
			/ * * /
			overflow: auto;
		}
		.news{
			height: 30px;
		}
	</style>
</head>
<body>
	<! -- Prepare a "container" -->
	<div id="test"></div>
	
	<! React core library -->
	<script type="text/javascript" src=".. / js / 17.0.1 / react. Development. Js. ""></script>
	<! React-dom () {react-dom ();
	<script type="text/javascript" src=".. / js / 17.0.1 / react - dom. Development. Js. ""></script>
	<! -- Introduce Babel to convert JSX to JS -->
	<script type="text/javascript" src=".. / js / 17.0.1 / Babel. Min. Js. ""></script>

	<script type="text/babel">
		class NewsList extends React.Component{

			state = {newsArr: []}componentDidMount(){
				setInterval(() = > {
					// Get the original state
					const {newsArr} = this.state
					// Simulate a news item
					const news = 'news'+ (newsArr.length+1)
					// Update the status
					this.setState({newsArr:[news,...newsArr]})
				}, 1000);
			}

			getSnapshotBeforeUpdate(){
				return this.refs.list.scrollHeight
			}

			componentDidUpdate(preProps,preState,height){
				this.refs.list.scrollTop += this.refs.list.scrollHeight - height
			}

			render(){
				return(
					<div className="list" ref="list">
						{
							this.state.newsArr.map((n,index)=>{
								return <div key={index} className="news">{n}</div>})}</div>
				)
			}
		}
		ReactDOM.render(<NewsList/>.document.getElementById('test'))
	</script>
</body>
</html>
Copy the code

4.3 Three important hooks

    1. Render: Initialize render or update render call
    1. ComponentDidMount: Enables listening to send Ajax requests
    1. ComponentWillUnmount: Do some finishing touches, such as cleaning timers

4.4 Obsolete hooks

    1. componentWillMount
    1. componentWillReceiveProps
    1. componentWillUpdate

If used now, there will be a warning, the next big version will need to be prefixed with UNSAFE_ to use, it may be completely deprecated, not recommended.

5. Virtual DOM and DOM Diffing algorithm

Schematic diagram:

Diffing algorithm

<script type="text/babel">
            class Time extends React.Component {
                    state = {date: new Date()}

                    componentDidMount () {
                            setInterval(() = > {
                                    this.setState({
                                            date: new Date()})},1000)
                    }

                    render () {
                            return (
                                    <div>
                                            <h1>hello</h1>
                                            <input type="text"/>
                                            <span>Now is: {this. State. Date. ToTimeString ()}<input type="text"/>
                                            </span>
                                    </div>
                            )
                    }
            }

            ReactDOM.render(<Time/>.document.getElementById('test'))
</script>
Copy the code

The key role

<script type="text/babel">
	React /vue react/vue (What's the inner workings of Key?) 2). Why is it best not to use index for key when iterating through a list? 1). To put it simply: The key is the identification of the virtual DOM object and plays an extremely important role in updating the display. 2). When the data in the state changes, React generates a new virtual DOM based on the new data. Then React makes a diff comparison between the new virtual DOM and the old virtual DOM. The same key is found in the old virtual DOM as in the new virtual DOM: (1). If the content in the virtual DOM remains unchanged, use the previous real DOM (2) directly. If the content in the virtual DOM changes, a new real DOM is generated, which then replaces the previous real DOM b. in the page. The old virtual DOM does not have the same key as the new virtual DOM. Create a new real DOM based on the data and render it to the page 2. Using index as key may cause the following problems: 1. If the data is added in reverse order, deleted in reverse order and other operations out of order, unnecessary real DOM updates will be generated. 2. If the structure also contains input class DOM: error DOM update ==> interface problems. 3. Pay attention! It is ok to use index as key if there is no order breaking operation such as adding or deleting data in reverse order and only used for rendering list for display. 3. How to select key in development? 1. It is better to use the unique identifier of each piece of data as the key, such as ID, mobile phone number, ID number, student number and other unique values. 2. If you are sure to simply display data, use index. * /
	
	{id:1,name:' xiao Zhang ',age:18}, {id:2,name:' Xiao Li ',age:19}, initial virtual DOM: {id:1,name:' Xiao Li ',age:19} < li key = 0 > zhang - 18 < input type = "text" / > < / li > < li key = 1 > xiao li - 19 < input type = "text" / > < / li > updated data: {id: 3, name: "wang", the age: 20}, {id: 1, name: 'xiao zhang, age: 18}, {id: 2, name: xiao li, age: 19}, update the data after the virtual DOM: < li key = 0 > wang - 20 < input type = "text" / > < / li > < li key = 1 > zhang - 18 < input type = "text" / > < / li > < li key = 2 > xiao li - 19 < input Type = "text" / > < / li > -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- slow-motion replay - use id uniquely identifies as a key initial data: {id: 1, name: 'xiao zhang, age: 18}, {id: 2, name: xiao li, age: 19}, the initial virtual DOM: < li key = 1 > zhang - 18 < input type = "text" / > < / li > < li > key = 2 a: xiao li - 19 < input type = "text" / > < / li > updated data: {id: 3, name: "wang", the age: 20}, {id: 1, name: 'xiao zhang, age: 18}, {id: 2, name: xiao li, age: 19}, update the data after the virtual DOM: < li key = 3 > wang - 20 < input type = "text" / > < / li > < li key = 1 > zhang - 18 < input type = "text" / > < / li > < li key = 2 > xiao li - 19 < input type="text"/> */
	class Person extends React.Component{

		state = {
			persons:[
				{id:1.name:'zhang'.age:18},
				{id:2.name:'xiao li'.age:19},
			]
		}

		add = () = >{
			const {persons} = this.state
			const p = {id:persons.length+1.name:'wang'.age:20}
			this.setState({persons:[p,...persons]})
		}

		render(){
			return (
				<div>
					<h2>Display personnel information</h2>
					<button onClick={this.add}>Add a little wang</button>
					<h3>Use index as the key</h3>
					<ul>
						{
							this.state.persons.map((personObj,index)=>{
								return <li key={index}>{personObj.name}---{personObj.age}<input type="text"/></li>})}</ul>
					<hr/>
					<hr/>
					<h3>Use id (the unique identification of the data) as the key</h3>
					<ul>
						{
							this.state.persons.map((personObj)=>{
								return <li key={personObj.id}>{personObj.name}---{personObj.age}<input type="text"/></li>})}</ul>
				</div>
			)
		}
	}

	ReactDOM.render(<Person/>.document.getElementById('test'))
</script>
Copy the code