Learning notes of react advanced guidance 3

Time:2021-1-21

Profiler

This component implements a simple test of the rendering time of the wrapped component, mainly the settingidAttributes andonRenderFunction returns the corresponding test results. amongonRenderThe return values of are:

  • id: string-SubmittedProfilerTreelikeid. If there are multiple profilers, it can be used to distinguish which part of the tree has been “committed”.
  • phase: "mount" | "update"-Determine whether the re rendering is caused by the first loading of the component tree, or by changes in props, state, or hooks.
  • actualDuration: number-This update is in the renderingProfilerAnd the time it spends on its children. This value shows how well memory can perform. (e.gReact.memouseMemoshouldComponentUpdate)。 Ideally, this value should drop significantly after the first load, since the offspring will only be re rendered due to specific prop changes.
  • baseDuration: number-InProfilerThe last time each component in the treerenderThe duration of the test. This value estimates the worst rendering time. (for example, when it is loaded for the first time or when the component tree does not use memoization).
  • startTime: number-The timestamp of react start rendering in this update.
  • commitTime: number-The timestamp of the end of the react commit phase in this update. In a commit, this value is shared among all profilers and can be grouped on demand.
  • interactions: Set-When updates are made,“interactions”Will be tracked. (for example, whenrenderperhapssetStateWhen called).

The above is quoted fromReact website

Show the effect through a simple demo:

import React, { Component, Profiler } from "react";
import styles from "./styles.module.less";

class Test extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  componentDidMount() {
    console.log("test");
  }
  callback = (id, ...props) => {
    let params = {
      ...props,
    };
    console.log (` time to view ${ID}, params));
  };
  render() {
    return (
      <div className={styles.contain}>
        <Profiler id="testPro" onRender={this.callback}>
          < button > test
        </Profiler>
      </div>
    );
  }
}

export default Test;

The demo above is used to test the rendering speed of the button component. The result of the console printing is as follows:Learning notes of react advanced guidance 3

Do not use ES6

Although it’s probably impossible to have a convenient ES6, to write that long string of code by yourself, but I still took a look at the basic.

The main differences are the syntax of creating components

type es6 Do not use ES6
class class Counter extends React.Component {} var Counter = createReactClass({});
state this.state getInitialState: function() {return {count: this.props.initialCount};}
bind this.handleClick = this.handleClick.bind(this)Or use the arrow function Automatic binding
mixin I won’t support it support

Don’t use JSX

As I said before,JSXjustreactThe syntax of sugar, so that you can more easily program, if it is their own configurationwebpack, don’t want more cumbersome configurationJSXRelated content, not usedJSXIt’s the same, but the originalJSXChange the way you write it toReact.createElement()Function.

There is a simplified way to write it

const e = React.createElement

ReactDOM.render(
  e('div', null, 'Hello World'),
  document.getElementById('root')
);

coordinate

This section mainly talks aboutreactFor updating componentsdiffingAlgorithm design decision, in order to make the program more accurate implementation of the purpose of the writer, for the realization of some functions, part of the parameter configuration, need to be as far as possibleCoordinate demand satisfaction and performance consumption

Diffing algorithm

  • Compare different root elements: if the root element is different, directly unload the original root element and reload the new one.
    The life cycle is as follows:
    componentWillUnmount(): uninstall component, existingstateDestruction
    componentWillMount(): new element will start loading, newstateinitialization
    componentDidMount(): component loading completed
  • Comparing elements of the same type: if the elements are consistent, it changes the attribute in the element. If the style changes, it updates the changed item.
  • Compare component elements of the same type: because the type is consistent, the component instance will be retained to ensure the consistency of the component state rendering. Therefore, the internal life cycle only needs to call the updated part
    componentWillReceiveProps(): whenpropsIt can be used internally when changes occurthis.setState()To updatestateCall update here does not trigger additionalrender
    componentWillUpdate(): whenpropsandstateExecute when changes occur, except initializationrenderOther thanrenderAfter that, it can not be used internallythis.setState()After the call, thenextPropsandnextStateUpdate existingthis.propsandthis.state

After the life cycle, call the previousdiffingTo update and render the whole component tree.

PS: in this algorithm, if you insert an element into an existing element, the entire root element will be unloaded first and a new element will be reconstructed. This will cause a large performance consumption, which is probably one of the reasons that react does not recommend DOM operation

PS: the performance consumption of algorithm switching between different types is much higher than that of the same type, so when the output is similar, the same type of components should be used as much as possible

Keys

When we use traversal array rendering, we need to set thekeyBut try to avoid using the subscript of an array as the valuekeyValue input. Because doing so may cause the contents of controllable components to display exception when inserting and rearranging arrays.

At the same time, if we use methods such as random numbers to generate akeyValue (e.g. usingMath.random())And use it every timerenderWill trigger the operation of unloading elements and refactoring components, which will cause a lot of unnecessary performance consumption, as well as the state loss of some sub components.

Refs & DOM

As I said before, it was approvedRefsForward to get instances of common elements or component elements, so as to realize the query outside the data flowdomModify (above)refsThe forwarding method only supportsreact16.3Above).

  • applyrefsThe following is the case:

Manage focus, text selection or media playback.
Trigger force animation.
Integrated third partyDOMLibrary.
Avoid usingrefsTo do anything that can be done declaratively.

  • Expose the child component DOM to the parent component

reactIt’s not recommended to do this unless you have to
In version 16.3 and above, you can useReact.forwardRefrealization
Below 16.3 or want to use more flexiblyref, you can use some aliasespropsPass downrefFor example:<Comp inputRef = { this.ref } />

CallbackRefs

CallbackrefsIt’s like receiving a child component in the parent componentrefCallback result, which is modified according to the value returned by the child component. In the child component, the function of the parent component is called as the callback resultrefTo form a function oriented middlewarerefPenetration, the following code is quoted fromhttps://zh-hans.reactjs.org/d…

function CustomTextInput(props) {
  return (
    <div>
 <input ref={props.inputRef} /> </div>
  );
}

class Parent extends React.Component {
  render() {
    return (
      <CustomTextInput
 inputRef={el => this.inputElement = el}      />
    );
  }
}

It can be seen from the above exampleCustomTextInputComponent, callingprops.inputRefFunction asref, which is passed back to the parent componentParentComponent, and finally form the parent component usage controlthis.inputElementGet subcomponentsDOMThe purpose of the project.

It should be noted that the callback should be avoided as far as possiblerefWrite it as an inline function. Because the inline function will be called twice when it is updated, it is better to write it as a binding function of a class

//Inline function
<div test = {()=>{
    this.setState({ test:false })
}}>

//Class
constructor(props){
    this.state={ test:true }
    this.changeTest= this.changeTest.bind(this) 
}
//Or use the arrow function
changeTest = () => {
    this.setState({ test:false })
}

Render Props

Render prop is a function that tells the component what to render

For example, in common use, we want to define a nice looking box. There may be a lot of unknown things in the box, but the outer packaging of the box is consistent. At this time, we want to have a component that can customize the received rendering content without changing the outer layer. Based on this, the common methods are as follows:

class Box extend Component{
    render(){
        return (
            <div style={padding:2,mrgin:4,backgroundColor:'red'}>
                {this.props.children}
            </div>
        )
    }
}

In the above example, we defined a box with a red bottom, an inner border of 2px, and an outer border of 4PXthis.props.childrenTo receive the rendered content from the outside world, and directly package it from the outside world

<Box>{'test: input a props children'}</Box>

This is a simple exampleRender PropsIn this case, we don’t need to define achildrenOfpropAttribute, becausereactDefaultchildrenProperty unless you manually change it yourself. In addition, you can also use your own defined attributes, such as:

<Test render={(test)=>{
    return <div> {test} <div>
}}

//Define a red box as above
function Test(props){
     return (
        <div style={padding:2,mrgin:4,backgroundColor:'red'}>
            {props.render}
        </div>
    )
}

In addition, useRender PropsCan be very convenient to generate a hoc, you can put the rendering content in the box, dynamic through the parameters into it.

PS: in useReact.PureComponentWhen generating components, it may causeRender PropsThe problem of failure, because

React.PureComponentInshouldComponentUpdate()Only shallow comparison of objects. If the object contains complex data structure, it may be unable to check the deep differences, resulting in wrong comparison results. (quoted fromhttps://zh-hans.reactjs.org/d…

The result is thatrenderEvery one of thempropsIt’s all different, which destroys the rendering.—-However, I have tested it for a long time according to the example of the official website, and I have not seen any abnormal phenomenon🙁Then find the difference and fill the hole

Recommended Today

Pandas data analysis — detailed explanation of super easy to use groupby

WeChat official account: “Python reads money”If there are any questions or suggestions, please official account message. In the daily data analysis, it is often necessary to analyze the dataDivide into different groups according to one (more) fieldFor example, in the field of e-commerce, the total sales of the whole country are divided by provinces, and […]