Do you know how to use React?

Basic use – often used, must know

React Advanced features — Not often used, but in depth, reviewed in the next article.

Remember, remember, remember, remember remember remember remember remember remember remember remember remember remember remember

Redux is used with react-router, and Redux is used with react-router.

React Basics Interview questions:

React typical interview questions

  • How does the React component communicate

  • What is the nature of JSX?

  • What is context? What is it for?

  • The purpose of the shouldComponentUpdate

  • Describes redux monomial data flows

  • Is setState synchronous or asynchronous?

1. The JSX syntax

  • Variables, expressions
  • class style
  • Child elements and components
const rawHtml=' Rich text content < I > italics 
       '
const rawHtmlData={
  __html:rawHtml// Note that it must be in this format
}
// 

{rawHtml}

const rawHtmlElem=<div> <p dangerouslySetInnerHTML={rawHtmlData}></p> <p>{rawHtml}</p> </div> return rawHtmlElem Copy the code

Condition of 2.

  • If else
  • Ternary expression
  • Logical operators && | |

3. List rendering

  • Map returns the new array, leaving the original array unchanged
  • key

4. Event

4.1 bind this

  • This defaults to undefined. Bind to change this to refer to; this.clickHandler = this.clickHandler.bind(this)

  • Static method, this refers to the current instance

clickHandler2 = () => {

this.setState({

name: 'lisi'

})

}

4.2 About the Event parameter

// event
       return <a href="https://imooc.com/" onClick={this.clickHandler3}>
           click me
       </a>
       
      / / for the event
   clickHandler3 = (event) = > {
       event.preventDefault() // Prevents default behavior from jumping
       event.stopPropagation() // Prevent bubbling
       console.log('target', event.target) // Refers to the current element, i.e. the current element is triggered
       console.log('current target', event.currentTarget) // Point to the current element, false!!
 
       // React encapsulates event. __proto__. Constructor is a SyntheticEvent
       console.log('event', event) // Not a native Event, a native MouseEvent
       console.log('event.__proto__.constructor', event.__proto__.constructor)
 
       // The native event is as follows. Its __proto__. The constructor is MouseEvent
       console.log('nativeEvent', event.nativeEvent)
       console.log('nativeEvent target', event.nativeEvent.target)  // Refers to the current element, i.e. the current element is triggered
       console.log('nativeEvent current target', event.nativeEvent.currentTarget) // Point to document!!
   }
Copy the code
  1. Event is a SyntheticEvent that simulates all the capabilities of DOM events
  2. Event. nativeEvent is a nativeEvent object
  3. All of the events are mounted on document
  4. Not the same as DOM events, not the same as Vue events

Pass custom parameters

// Pass arguments - bind(this, a, b)
        return <ul>{this.state.list.map((item, index) => {
            return <li key={item.id} onClick={this.clickHandler4.bind(this, item.id.item.title)} >
                index {index}; title {item.title}
            </li>
        })}</ul>
        // Pass parameters
    clickHandler4(id, title, event) {
        console.log(id, title)
        console.log('event', event) // Add a final parameter to receive the event
    }
Copy the code

4.3 the form

The controlled components

return <div>
            <p>{this.state.name}</p>
            <label htmlFor="inputName">Name:</label>{/* replace for */} with htmlFor<input id="inputName" value={this.state.name} onChange={this.onInputChange}/>
        </div>
Copy the code

5. Parent-child component communication – Components and Props (Type Checking)

import React from 'react'
import PropTypes from 'prop-types'

/ / child component
class Input extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            title: ' '}}render() {
        return <div>
            <input value={this.state.title} onChange={this.onTitleChange}/>
            <button onClick={this.onSubmit}>submit</button>
        </div>
    }
    onTitleChange = (e) = > {
        this.setState({
            title: e.target.value
        })
    }
    onSubmit = () = > {
        const { submitTitle } = this.props
        // The child calls the parent method and updates the data in the parent
        submitTitle(this.state.title) // 'abc'

        this.setState({
            title: ' '}}})// props type check
Input.propTypes = {
    submitTitle: PropTypes.func.isRequired
}

/ / child component
class List extends React.Component {
    constructor(props) {
        super(props)
    }
    render() {
        const { list } = this.props

        return <ul>{list.map((item, index) => {
            return <li key={item.id}>
                <span>{item.title}</span>
            </li>
        })}</ul>}}// props type check
List.propTypes = {
    list: PropTypes.arrayOf(PropTypes.object).isRequired
}

/ / child component
class Footer extends React.Component {
    constructor(props) {
        super(props)
    }
    render() {
        return <p>
            {this.props.text}
            {this.props.length}
        </p>
    }
    componentDidUpdate() {
        console.log('footer did update')}shouldComponentUpdate(nextProps, nextState) {
        if(nextProps.text ! = =this.props.text || nextProps.length ! = =this.props.length) {
            return true // Can render
        }
        return false // Do not repeat rendering
    }

    // React default: the parent component is updated and the child component is updated unconditionally!!
    // Performance tuning is more important for React!
    // Does the SCU have to be used every time? Optimize when needed
}

/ / the parent component
class TodoListDemo extends React.Component {
    constructor(props) {
        super(props)
        // The status (data) is improved
        this.state = {
            list: [{id: 'id-1'.title: 'heading 1'
                },
                {
                    id: 'id-2'.title: 'title 2'
                },
                {
                    id: 'id-3'.title: 'title'}].footerInfo: 'Bottom text'}}render() {
        return <div>
            <Input submitTitle={this.onSubmitTitle}/>
            <List list={this.state.list}/>
            <Footer text={this.state.footerInfo} length={this.state.list.length}/>
        </div>
    }
    // Parent component method
    onSubmitTitle = (title) = > {
        this.setState({
            list: this.state.list.concat({
                id: `id-The ${Date.now()}`,
                title
            })
        })
    }
}

export default TodoListDemo

Copy the code

6. The state and setState

6.1 Immutable values

First, state is defined in the constructor

constructor(props) {
        super(props)

        // First, state is defined in the constructor
        this.state = {
            count: 0}}Copy the code

Second, do not change state directly; use immutable values

// this.state.count++ // error
this.setState({
            count: this.state.count + 1 // SCU
        })
Copy the code

A common form of manipulation of arrays and objects

Why does setState use immutable values?

The setState value cannot be changed in advance, but can be set whenever we want to change it without affecting the previous value.

// Immutable values (functional programming, pure functions) - arrays
const list5Copy = this.state.list5.slice()
list5Copy.splice(2.0.'a') // Insert/delete in between
this.setState({
    list1: this.state.list1.concat(100), / / append
    list2: [...this.state.list2, 100]./ / append
    list3: this.state.list3.slice(0.3), / / interception
    list4: this.state.list4.filter(item= > item > 100), / / filter
    list5: list5Copy // Other operations
})
// Note that you cannot push pop splice, etc. on this.state.list directly, as this violates immutable values

// Immutable value - object
this.setState({
    obj1: Object.assign({}, this.state.obj1, {a: 100}),
    obj2: {... this.state.obj2,a: 100}})// Note that this.state.obj cannot be set directly as it violates immutable values
Copy the code

6.2 It may be an asynchronous update

Is setState synchronous or asynchronous?

SetState may be asynchronously updated (it may be synchronous)

  • SetState is synchronized in setTimeout
  • For self-defined DOM events, setState is synchronized
 / / third, setState may be asynchronous update (may be an update) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
        
        this.setState({
            count: this.state.count + 1
        }, () = > {
            Vue $nexttick-dom
            console.log('count by callback'.this.state.count) // The latest state is available in the callback function
        })
        console.log('count'.this.state.count) // Async, can not get the latest value



        // setState is synchronized in setTimeout
        setTimeout(() = > {
            this.setState({
                count: this.state.count + 1
            })
            console.log('count in setTimeout'.this.state.count)
        }, 0)



        // The setState of the DOM event is synchronized. Then componentDidMount
componentDidMount() {
        // The setState of the DOM event is synchronized
        document.body.addEventListener('click'.this.bodyClickHandler)
    }
bodyClickHandler = () = > {
        this.setState({
            count: this.state.count + 1
        })
        console.log('count in body event'.this.state.count)
    }
componentWillUnmount() {
        // Destroy custom DOM events in time
        document.body.removeEventListener('click'.this.bodyClickHandler)
        // clearTimeout
    }
Copy the code

6.3 It may be merged

In asynchronous cases, incoming objects will be merged (similar to object.assign). The result is +1 only once

this.setState({
            count: this.state.count + 1
        })
        this.setState({
            count: this.state.count + 1
        })
        this.setState({
            count: this.state.count + 1
        })
// 1 2 3 4 5 6
Copy the code

Passed functions are not merged. It will be executed one by one

this.setState((prevState, props) = > {
            return {
                count: prevState.count + 1}})this.setState((prevState, props) = > {
            return {
                count: prevState.count + 1}})this.setState((prevState, props) = > {
            return {
                count: prevState.count + 1}})// 3 6 9 12....
Copy the code

7. Component life cycle

Component life cycle diagram

7.1 Life Cycle of a Component

7.2 Life Cycle between Multiple Components

What about life cycles between multiple components? Like parent and child components? Sibling components? What about the cycles? What about asynchronous routes? The Hooks?

  1. Synchronous routing, parent component inrenderPhase creates child components.
  2. Asynchronous routing, where the parent component starts creating child components after it has mounted itself.
  3. After the mount is complete, the synchronous component is the same as the asynchronous component when updated.
  4. Either mount or update torenderCompletion is bounded by the parent component before the child component.
  5. Sibling components are executed roughly in the order they appear in the parent.
  6. useEffectExecution is delayed after the mount/update is complete.
  7. When an asynchronous request (such as an access API) gets a response is independent of the component’s life cycle, that is, an asynchronous request originating in the parent component is not guaranteed to get a response until the child component finishes mounting.

7.2.1 Mounting Process

There are three stages for mounting parent and child components.

In the first stage, the parent component performs its own Render, resolves which sub-components need to be rendered, creates the synchronized sub-components, executes each component one by one to Render, generates the Virtual DOM tree so far, and commits to the DOM.

In the second stage, the DOM node has been generated, the component has been mounted, and the subsequent process begins. ComponentDidMount/useLayoutEffect triggers the parent componentDidMount/useLayoutEffect.

In phase 3, if the component uses useEffect, useEffect is triggered after phase 2. If both parent and child components use useEffect, the child component fires first, followed by the parent component.

If the parent component contains a step-out component, it will be created after the parent component is mounted.

For sibling components, if they are synchronous routes, they are created in the same order as the exit order defined in the parent component.

If a component’s initialization process includes asynchronous operations (typically performed in componentDidMount() and useEffect(fn, [])), when those operations are responded is independent of the component’s life cycle and depends entirely on how long the asynchronous operation itself takes.

7.2.2 Update process

React is designed to follow a one-way data flow model. Communication between siblings also passes through the parent component (Redux and Context are also implemented by changing the props passed down from the parent component). Therefore, communication between any two components can essentially be attributed to the parent component updating leading to the child component updating.

Updates to parent and child components are also divided into three phases.

The first and third phases are basically the same as the mounting process. In the first phase, a Reconciliation process is added. In the third phase, the Cleanup function of useEffect needs to be executed first.

The second stage, similar to the mount process, is that the child component precedes the parent component, but the update involves more functions than the mount:

  1. getSnapshotBeforeUpdate()
  2. The Cleanup useLayoutEffect ()
  3. useLayoutEffect() / componentDidUpdate()

React executes these functions in the order shown above, with each function being executed first by its child component and then by its parent. GetSnapshotBeforeUpdate () for each child, then getSnapshotBeforeUpdate() for the parent, then componentDidUpdate() for each child, The parent component’s componentDidUpdate(), and so on.

Here we put the class component and the Hooks lifecycle functions together, because parent components can be any combination of the two component types. Not every function will be useful in actual rendering, only the functions that the component actually owns will be called.

7.2.3 Uninstallation Process

The uninstallation process involves three functions: Cleanup of componentWillUnmount(), useEffect(), and Cleanup of useLayoutEffect(). The parent component is executed first. The child components execute their respective methods in the order defined in JSX.

Note that the Cleanup function is executed in the order defined in the code, regardless of the function’s nature.

If the uninstallation of the old component is accompanied by the creation of the new component, the new component is first created and executes render, then unloads the old component that is not needed, and finally the new component performs the mounted completed callback.

7.3 What is special about the Hooks lifecycle

React useEffect() and useLayoutEffect() are equivalent to componentDidUpdate()/componentDidMount(), but they differ in some details:

7.31 First come is not always first go

UseLayoutEffect () always executes before useEffect(), even if useEffect() comes first in your code. So useLayoutEffect() is actually componentDidUpdate()/componentDidMount().

UseEffect () is triggered only after both componentDidUpdate() and componentDidMount() are triggered for the parent component. When both parent and child components use useEffect(), the child component fires before the parent component.

7.32 Disunity Cleanup

As well as having the Cleanup function, useLayoutEffect() and its Cleanup are not necessarily adjacent.

Cleanup of useLayoutEffect() is called between getSnapshotBeforeUpdate() and componentDidUpdate() when the parent component is Hooks and the child component is Class. UseLayoutEffect () is invoked in the same order as componentDidUpdate().

This is the same process with Hooks as child components, only without them it is less obvious.

UseEffect (), on the other hand, is tightly bound to its Cleanup, which never separates from each other.

Thank you for reading

❤️ follow + like + favorites + comments + forward ❤️, original is not easy, encourage the author to create better articles

Small round face, a focus on the web front-end foundation, engineering, interview front-end public number, occasionally hair life