The first time I got to know React was in July 2016. I remember it was very difficult for me to change from JQ thinking at the beginning of learning React to being in a predicament, haha. Later, I slowly tried to let myself out of the manual manipulation of DOM, forget JQ, slowly adapt to come over, beginners generally have this experience, right? Remember when it was 15 version, it feels like a long time ago, oh, old. React has been updated quite quickly in recent years. Now it is version 17. This article mainly relearns version 16.3 and writes some notes to help you learn and digest React.

1、为什么使用React

React is a JS library for building user interfaces. It is componentized, declarative, and optimized for DOM performance. It’s an incremental framework.

For example, when building a project, developers only need React and can only introduce React. When the project has new requirements, they can introduce other class libraries, such as routing library and state management library.

1.1. Focus on the view layer

React focuses on the View layer solution. When using React, you only need to tell React what the View needs to look like or at what point in time to update the View. React takes care of View rendering, performance optimization and other issues.

1.2. Componentized development and declarative programming

React abstracts views into components, and then freely combines them to form a complete view. Improve development efficiency, facilitate later maintenance, testing is also convenient.

In traditional project development, imperative programming is usually adopted. The way commands are given step by step is imperative programming.

React follows declarative programming, which is logical and easy to read and maintain.

Difference between declarative and imperative:

Imperative programming is about process, where the developer tells the program what to do at each step. Declarative programming is about results, which tells the program what to doCopy the code

1.3, Virtual DOM

In React, each component generates a virtual DOM tree. The DOM tree describes the view (the real DOM) as a pure object.

React generates the real DOM from the virtual DOM generated by the component. React generates a new virtual DOM after the data in the component changes. React compares the old and new virtual DOM to find the nodes that have changed, and then re-renders only the nodes that have changed. This greatly improves the performance of re-rendering.

2, ReactDOM

// React core files, such as components, Hooks, virtual DOM... <script SRC ="js/react.js"></script> // Operations on the real DOM, such as rendering the virtual DOM to the real DOM, <script SRC ="js/react-dom.js"></script> //Copy the code

2.1, render

Reactdom.render (Element, container[, callback]) // The render method is used to render the React generated virtual DOM into the real DOM. // Element is a virtual DOM generated by React, also known as ReactElement or ReactNode. It can also be implemented using strings. // container The container in which to place element must be an existing real DOM node. // Callback is the callback function after rendering the ReactNode to the Container.Copy the code

2.2, hydrate

ReactDOM.hydrate(element, container[, callback])
Copy the code

Usually used with React SSR, hydrate preserves as much structure as possible and complements features such as event binding when ReactDOM reuses ReactDOMServer server renderings.

2.3, findDOMNode

ReactDOM.findDOMNode(Component)
Copy the code

Component refers to the React Component. If the Component is already rendered into the DOM, you can retrieve the actual DOM by findDOMNode.

2.4, unmountComponentAtNode

ReactDOM.unmountComponentAtNode(container)
Copy the code

Used to remove the installed React component from the Container and clean up its event handlers and state. If there are no components installed in the container, nothing happens when you call this function. Returns true if the component has been unmounted; If the component is not unloaded, false is returned.

2.5, createPortal

ReactDOM.createPortal(reactNode, newContainer)
Copy the code

Used to add nodes to a new container other than the container to which the parent component belongs. Must be a real DOM node.

Note: It is not recommended to use these apis directly in projects other than the Render method, and there is generally no requirement to use apis other than Render in real projects.

React view rendering

Building views has been the focus of React, from createElement to JSX.

3.1, ReactElement

React provides a method createElement() specifically for creating a virtual DOM with React. Note that this method is not createElement in the native DOM.

CreateElement (type, Congfig, children) // type Specifies the type of tag to be created. String // Congfig sets the attributes associated with the generated nodeCopy the code

The createElement method is used to create the ReactElement, the virtual DOM in React.

There are two issues to be aware of when using Congfig:

Congfig can be null if no attribute needs to be defined but children parameter needs to be passed. 2.Copy the code

When using children, there are three different ways to write it:

1. When children is a string, it means adding text to the element. 2. If children is an array, expand the contents of the array into an element. 3. When children are ReactElement, they are added as children of the element. When you need to add more than one child node, you can always write after it.Copy the code

Writing views this way is extremely unclear and not recommended. So React provides a view-writing artifact called JSX.

3.2, JSX

JSX = JS + XML, is a JS syntax extension that looks a lot like XML.

JSX is a JS syntax extension, but the browser does not recognize these extensions, so you need to compile JSX with babel.js to make it a browser-aware syntax, i.e. React. CreateElement.

Note:

Type ="text/bable"; type="text/bable";Copy the code

JSX itself is a value, which is a ReactElement, not a string.

3.2.1. Interpolation

When using interpolation, note a few things:

1, {}, receive a JS expression, can be an expression, variable or function call, etc. An expression means that a value must be returned, and interpolation means that the value evaluated by the expression is inserted into the view. In {}, when receiving a function call, the function needs to return a value. 3. Strings and numbers are displayed as they are. 4, Boolean, null, undefined will output null value, there will be no error. 5. Arrays can be output directly. By default, the array hyphen (,) is replaced with null and then output directly. 6. Objects cannot be output directly, but they can be parsed in other ways, such as object. value, object. keys, etc., and converted into arrays for output.Copy the code

There are several special rendering cases:

1, 2, conditions apply colours to a drawing list rendering (&& (and), | | (or), three unary function)Copy the code

3.2.2 JSX attribute writing

JSX attribute writing Notes:

2. If the value of the attribute is a string and is fixed, it can be written directly. If the value of an attribute is non-string or dynamic, interpolation must be used. Some special attribute names cannot be used directly: HtmlFor 3), colspan 5), style received as an objectCopy the code

3.2.3 JSX Matters needing attention

JSX Notes summary:

JSX should not be written as a string, otherwise the tag will be printed as text. JSX is a value that can only be output with a single top-level tag. You can use < react. Fragment></ react. Fragment> as the top-level tag. 2) Fragment is a container component provided by React, which itself is not rendered in the real DOM. React <></> <React.Fragment/> JSX is not HTML, and many attributes are written differently. 1) Attribute names must follow the hump nomenclature, capitalizing the first letter from the second word. 2) Individual attribute names may change. In JSX, insert data with interpolation {data}Copy the code

4, the create – react – app

To reduce the complexity of development, a number of good solutions have emerged:

1, modular development 2, Less, Saas and other CSS syntax extension 3, TS and other JS syntax extensionCopy the code

4.1, the React. StrictMode

StrictMode is a tool used to check for potential risks in a project, similar to the StrictMode in JS. Like fragments, no real DOM is rendered. Just trigger extra checks and warnings for descendant elements.

StrictMode can be used anywhere in code, or directly in index.js to enable global detection.

StrictMode only works in development mode and does not conflict with production mode.

1. Identify components with unsafe life cycles. 2. Warning about old string ref usageCopy the code

All are in the console output warning ⚠️!

5. Define the React component

React advocates componentized development. When you write a project with React, you abstract the view into its components, which are then used to assemble the desired view.

React writes components in two ways:

Class components 2. Functional componentsCopy the code

5.1. Class Components

React.Component
render
Copy the code

6. Communication between components

6.1. Use of props

There’s really nothing to say about this… To add: ES6 deconstruction is recommended.

6.2 use of state

Let’s not be too lazy. Let’s add a code:

class App extends Component{ constructor(props){ super(props) this.state = { name: 'zhangsan'}} render(){let {name} = this.state return (<div> name: {name}</div>)}Copy the code

Class /extends extends from react.component. so the super keyword is used to access and call functions on the parent object of an object. When used in constructors, the super keyword appears alone and must be used before the this keyword. The super keyword can also be used to call functions on parent objects.

Modify the data with setState(). It takes two kinds of arguments, an object, and a function that returns a value, which returns an object. This method is asynchronous. Multiple setstates () are merged, but cause an attempt to render

6.3 Communication between components

Parent communicates with child: props 2. Child communicates with parent: callback method 3. Pass between sibling components: callback method of parent component, pass to sibling componentCopy the code

6.4. Cross-component communication

const context = createContext()
const {Provider, Consumer} = context;
Copy the code

Calling the createContent method returns two components, Provider and Consumer. A Provider component is used to pass data to its descendants by adding the subset of data to the Provider’s value property. The Consumer component is used to receive data from the parent. In Consumer, you can write a function that passes data from the parent as arguments to the function.

The following is an example:

1. Create a context.js file, create a context in context.js, and export context, Provider, and Consumer

import {createContext} from 'react'

const context = createContext()
const {Provider, Consumer} = context;

export {Provider, Consumer}
export default context
Copy the code

2. Modify the app.js file

import React, {Component} from 'react' import Child from './child' import {Provider} from './context' calss App extends Component{ Render () {return (<Provider value={{info: 'transfer data'}}> <Child /> </Provider>)}} export default AppCopy the code

3. Create the child.js file

import React, {Component} from 'react'
import {Consumer} from './context'

class Child extends Component{
    render() {
        return (
            <Consumer>
                {(val)=>{
                    return <p>{val.info}</p>
                }}
            </Consumer>
        )
    }
}

export default Child
Copy the code

It can also be received via the class contextType, and then retrieved from the component’s context property.

import React, {Component} from 'react'
import context from './content'

class Child extends Component{
    static contextType = context
    
    render(){
        return <p>{this.context.info}</p>
    }
}

Child.contextType = context
export default Child
Copy the code

7. Component lifecycle

The React component lifecycle is divided into three phases:

Mounting Phase (Mounting) The Mounting phase starts with the component initialization and continues until the component is created and rendered into the DOM. Updating as the name implies, the component has been updated. This phase starts Updating the component and monitors it until the component has been updated and the DOM has been re-rendered. Unmounting Stage (Unmounting) At this stage, the listener component is unmounted from the DOM.Copy the code

7.1 Mount stage life cycle function

Constructor (props) Initialize this component, adding super

Static getDerivedStateFromProps(props,state) getDerivedStateFromProps(props,state) getDerivedStateFromProps(props,state) Note:

1. This is a static method and cannot be used internally. 2, is added after version 16.3, use need to pay attention to version number. 3. There must be a return value, which is a modification of state. This.setdata () is the same as this.setdata (). The function is props for modifying state, so the component must initially define the state propertyCopy the code

3, componentWillMount will be mounted, note:

1. Not recommended after version 16.3. This parameter cannot be used with getDerivedStateFromProps.Copy the code

The value of render return generates the virtual DOM, which is then submitted to the ReactDOM to render the real DOM

The componentDidMount component has been mounted, and the virtual DOM has been added to the real DOM.

Class App extends Component{constructor(props){super(props) console.log("1-- Component initialization ") this.state = {}} static GetDerivedStateFromProps (props,state){console.log("2-- map props to state") return {state: 1}} componentWillMount(){console.log("3-- components are about to be mounted ")} render(){console.log("4-- generates virtual DOM from return ") return <div> Hello React </div>} componentDidMount(){console.log("5-- components already mounted, virtual DOM already added to the real DOM")}}Copy the code

7.2 Update phase life cycle function

There are three different processes in the React component update lifecycle:

1. Current component updates caused by parent component updates 2. Current component updates itself 3Copy the code

There is a big change in version 16.3, so I will not mention the use method before version 16.3, after all, try to use the latest.

7.2.1. Current component updates caused by parent component updates

Static getDerivedStateFromProps(newProps,newState) getDerivedStateFromProps(newProps,newState) getDerivedStateFromProps(newProps,newState) getDerivedStateFromProps(newProps,newState

ShouldComponetUpdate check whether the component is updated

Render generates a new virtual DOM

GetSnapshotBeforeUpdate (prevProps,prevState) get the DOM snapshot before rendering

1. This. State and this. Props are up to date. There must be a return value, which is passed to componentDidUpdateCopy the code

5, componentDidUpdate (prevProps prevState, snapshot) receive the snapshot getSnapshotBeforeUpdate return values passed through information.

Class App extends Component{constructor(props){super(props) console.log("1-- Component initialization ") this.state = {}} static GetDerivedStateFromProps (props,state){console.log("2-- map props to state") console.log("6-- get new props and state") return { The state: 1}} componentWillMount(){console.log("3-- componentWillMount ")} render(){console.log("4-- componentWillMount ") Console. log("8-- componentDidMount ") return <div>hello React </div>} componentDidMount(){console.log("5-- componentDidMount, } shouldComponetUpdate(newProps,newState){console.log("7-- check if the component needs to be updated ") return true} GetSnapshotBeforeUpdate (prevProps,prevState){console.log("9-- DOM for getting updates ") return {info: 'to pass information to the componentDidUpdate'}} componentDidUpdate (prevProps prevState, snapshot) {the console. The log (" 10 "-- component upgrade is complete, the snapshot)}}Copy the code

7.2.2. The current component updates itself

The component updates itself by calling setState inside the component, causing the current component to update. It has gone through three versions: before 16.3, 16.3, 16.4 and later. In this or the latest to do the main explanation.

Order: static getDerivedStateFromProps(props,state) —> shouldComponetUpdate(newProps,newState) —-> render —-> getSnapshotBeforeUpdate —-> componentDidUpdate

7.2.3, forceUpdate

ForceUpdate is a forceUpdate that can be used when a component depends on data that is not state and changes the view. An update attempt is forced, so the lifecycle is slightly different from other updates and shouldComponetUpdate is not called.

let name = 'zhangsan' class App extends Componet{ render(){ <div> <div>{name}</div> <button onClick={()=>{ name = "lisi" This.forceupdate ()}}> Update name </button> </div>}}Copy the code

7.3 Life cycle function of unloading stage

Component unload is to remove the component from the DOM.

ComponentWillUnmount componentWillUnmount componentWillUnmount componentWillUnmount componentWillUnmount

8 ref.

When developing a project, there are special cases where you need to use native DOM nodes, usually using javascript native methods such as getElementById. React also provides us with an API: ref.

8.1, string ref

class App extends Component{ componentDidMount(){ console.log(this.refs.parent, This.refs.child)} render(){return <div> <p ref="parent"> parent </p> < child ref="child"/> </div>}}Copy the code

Matters needing attention:

A ref can be customized for componentDidMount and componentDidUpdate, otherwise the ref has not been assigned or updated.Copy the code

8.2, createRef

163. The createRef method has been added

class App extends Component{ parent = createRef() child = createRef() componentDidMount(){ console.log(this.parent.current, This.child.current)} render(){return <div> <p ref={this.parent}> parent </p> < child ref={this.child} /> </div>}}Copy the code

9, the key

The key is used to give elements a unique identity against which components can be compared when updated. The rule is to find the element with key 1 in the old virtual DOM and compare it with the element with key 1 in the new virtual DOM. Note:

1. Keep the same key before and after the same element. That is, the key of element A must be 1 before it is updated, and the key must be 1 after it is updated. React defaults the array index to key when no key is added. If the order is not changed, you can use the array index as the key. When the sequence changes, you are advised to use the ID (unique identifier of data) as the key.Copy the code

10. Add events

React uses a synthetic event rather than the native DOM event. The React element adds events somewhat like interline events, but with a slightly different twist. The interline event names are all lowercase, while React follows the camel’s name. Interline events accept strings, React via JSX and React via JSX interpolation into a function. Note:

1. This is undefined by default. If you want this to be the component instance, either bind this to the function or use the arrow functionCopy the code

11, forms,

11.1. Controlled Components

11.2 Uncontrolled Components

12. Other features

12.1, the children

The Children property is a special API in React that is used to pass content to render inside components.

class Popup extends Component{ render(){ let {title, children} = this.props return <div> <h2>{title}</h2> <div>{children}</div> </div> } } class App extends Componet{ Render (){return <Popup title=" custom Popup "> <div> Popup content </div> </Popup>}}Copy the code

12.2, dangerouslySetInnerHTML

DangerouslySetInnerHTML can help developers add InnerHTML directly to React elements.

class App extends Component{
    render(){
        return <div dangerouslyInnerHTML={{
            __html: `<div>hello react<div>`
        }}></div>
    }
}
Copy the code

12.3 functional Components

In addition to class components, there is a simple component in React: functional components. A functional component is a function that is a component. The first argument to the function is the props passed in by the parent, and the return value is the view to be output by the component.

function App(props){
    return <div>hello react</div> 
}
Copy the code

Prior to version 16.7, functional components had no way to define state and no lifecycle, and were often used as pure presentation components, so they were known as stateless components.

13, the React of Hooks

Finally, hooks. Personally, I like them. I’ve been using them for a year. Here’s the outline.

Hooks are a new feature in beta 16.7 and officially new in version 16.8. React helps solve a lot of tedious problems.

When using class components, a lot of business logic such as various interface requests needs to be placed in the life cycle functions such as componentDidMount and componentDidUpdate, which can make the component complex and difficult to maintain. And this problem in Class also causes many beginners to suffer when using it. There is also a lot of logic that is difficult to reuse with components, such as wanting only a method that can get the scrollbar position, or simply encapsulating a request method for a single interface. Function components can avoid this problem, but function components do not have features such as life cycles and states.

13.1. Hooks in use

13.1.1, usesState

const [state, setState] = useState(initState)
Copy the code

Sample code:

Import the React, {useState} from 'react' function App(){ const [Name, <div> <div>{Name}</div> <button onClick={()=>{setName('lisi')}}> </button> </div> } export default AppCopy the code

Matters needing attention:

1. The setState method returned by useStaet is also an asynchronous method like setState of the same component. The value of state will become a new value only after the component is updated. 2. The setState returned by useState does not have the same effect as the setState of the class component. If there are multiple states in the state, the other values will be updated with the update. 3. You can use useState to create multiple states in the same component.Copy the code

13.1.2, useRef

UseRef can be seen as a hook version of createRef. Sample code:

import React,{useRef} from 'react' function App(){ let myName = useRef() return <div> <div ref={myName}>hello Hooks </div> <button onClick={()=>{console.log(myname.current)}}> Export default AppCopy the code

13.1.3, useEffect

The technical term for this is a side Effect. What are side effects? Network requests and DOM operations are all side effects, and useEffect is specifically designed to deal with side effects. UseEffect is equivalent to a combination of componentDidMount, componentDidUpdate, and componentWillUnmount.

UseEffect takes two arguments: the callback function at execution and the dependent argument (array), and the callback function can have a return function. Code examples:

UseEffect (()=>{console.log(" Component hangs or updates ") return ()=>{console.log(" Cleans up some global content before the update, ")}},[num, num2, num3]) // The callback function is executed only when num or num1 or num2 is updatedCopy the code

The entire component lifecycle process:

Component mount 2. Perform side effects (callback function) 3. Component update 4. Perform cleanup function (callback function) 5Copy the code

Special circumstances note:

ComponentDidMount (componentDidMount) null for componentDidMount (componentDidMount) If you only want to execute componentWillUnmount (componentWillUnmount), the return function for this side effect will be executed before unmount (componentWillUnmount). 3, only detect the update is relatively troublesome (componentDidUpdate), in fact, is to judge the dependent data and the initial value is not consistent. Consistent means mount, inconsistent means update.Copy the code
In addition to binding DOM nodes, useRef is also used to store data across the render cycle, i.e., before the component is rendered. Let prevNum2 = useRef(num2) useEffect(()=>{if(num! ==prevNum.current || num2 ! == prevnum2.current){console.log(" component update ") // ref does not automatically update, PrevNum. Current = num precnum2. current = num2}},[])Copy the code

Which are Hooks that are used in the following paragraphs.

13.2. Use rules of hooks

Precautions for use:

Hooks can only be called from functional components and custom Hooks, not from normal functions or class components. 2. Only hooks can be called on the first level of this function. Hooks are designed to rely heavily on the order in which they are defined, and if the order in which hooks are called changes when components are updated, unpredictable problems can occur. Ensure the stability of their call order. Eslint-plugin-react-hooks Checks for canonical use, with error warnings in the development environment.Copy the code

13.3. Custom hooks

Custom hooks are perfect for solving problems where simple logic cannot be reused by components. So you can customize some reusable logic as hooks. Require the beginning of use to distinguish it from other functions.

Sample code:

function useScrollY(){
    let [ScrollY, setScrollY] = useState(0)
    function scroll(){
        setScrollY(window.scrollY)
    }
    useEffect(()=>{
        window.addEventListener("scroll", scroll);
        return ()=>{
            window.removeEventListener("scroll", scroll)
        }
    }, [])
    return scrollY
}
Copy the code

summary

React is changing fast. Keep an eye on the React website for updates. Improve your skills. Practice. This article is written a little brief, I hope not to understand or not enough in-depth place, we go to more information to learn, in order to master their own better!