Detailed explanation of class components and properties of React!

Posted by cmack on Sun, 28 Nov 2021 03:02:47 +0100

1, class component

React has two components: class component and function component. Class component needs to inherit React.Component. The usage is as follows:

class Welcome extends React.Component {
    render() {
        return <h1>Hello, {this.props.name}</h1>;
    }
}
1. Method that must be overridden

Every component that inherits React.Component must override the render() method.

2. Composition rather than inheritance

React recommends that you do not create custom base class components and write components in combination rather than inheritance.

2, Component lifecycle
1. Method operation map
2. Mount

When a component instance is created and inserted into the DOM, the calling sequence is as follows:

- constructor()
  • It is called before the component is mounted. The usage method and precautions are as follows:
constructor(props) {
    // 1. Be sure to write this sentence, otherwise this.props undefined bug will appear.
    super(props);

    // 2. The constructor is the only place that can initialize state, but do not call this.setState() to assign a value,
    // The render() method will be triggered, causing unnecessary bug s.
    this.state = { counter: 0 };

    // 3. Here you can bind the event handler function of the component
    this.handleClick = this.handleClick.bind(this);
}
- static getDerivedStateFromProps()
  • The function is to update the state according to the changes of props.
// It will be called during initial mount and subsequent updates,
static getDerivedStateFromProps(props, state)
- render()
- componentDidMount()
  • [call]: it will be called after the component is mounted (inserted into the DOM tree);
  • [use]: suitable for data initialization and network request to obtain data.
  • [note]: calling setState() here will trigger render(). Please use it carefully, which may lead to performance problems.
3. Renew

The update is triggered when the props or state of the component changes. The calling sequence is as follows:

- static getDerivedStateFromProps()
  • The function is to update the state according to the changes of props.
// It will be called during initial mount and subsequent updates,
static getDerivedStateFromProps(props, state)
- shouldComponentUpdate()

This method is only used for performance optimization. Return true, indicating that the component needs to be re rendered; Return false to skip rendering. The default return value is true.

  • Not called when rendering for the first time or using forceUpdate().
  • When state or props changes, shouldComponentUpdate() is called before rendering execution.
  • Deep comparisons in shouldComponentUpdate() or JSON.stringify() are not recommended. This will greatly affect efficiency and damage performance.
- render()
- getSnapshotBeforeUpdate()
  • Get some information (such as scroll position, etc.) before the component changes, and the return value will be passed to componentDidUpdate() as a parameter
// Function prototype
getSnapshotBeforeUpdate(prevProps, prevState)
// Use example
class ScrollingList extends React.Component {
    constructor(props) {
        super(props);
        this.listRef = React.createRef();
    }

    getSnapshotBeforeUpdate(prevProps, prevState) {
        // Do we add new items to the list?
        // Capture the scroll position so that we can adjust the scroll position later.
        if (prevProps.list.length < this.props.list.length) {
            const list = this.listRef.current;
            return list.scrollHeight - list.scrollTop;
        }
        return null;
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        // If our snapshot has a value, it means that we have just added new items,
        // Adjust the scroll position so that these new items do not push the old items out of the view.
        //(the snapshot here is the return value of getSnapshotBeforeUpdate)
        if (snapshot !== null) {
            const list = this.listRef.current;
            list.scrollTop = list.scrollHeight - snapshot;
        }
    }

    render() {
        return (
            <div ref={this.listRef}>{/* ...contents... */}</div>
        );
    }
}
- componentDidUpdate()
  • After the component is updated, it will be called, and this method will not be executed for the first rendering.
  • You can perform some custom operations, such as making some network data requests.
componentDidUpdate(prevProps) {
    // Typical usage (don't forget to compare props):
    if (this.props.userID !== prevProps.userID) {
        this.fetchData(this.props.userID);
    }
}
  • You can call setState(), but you must wrap setState() with conditional statements, otherwise rendering will enter an endless loop, because setState will trigger render(), and render() will call componentDidUpdate. Please use with caution.
  • componentDidUpdate() is not called if shouldComponentUpdate() returns false.
4. Unload
- componentWillUnmount()
  • Called when the component is removed from the DOM (before unloading and destroying).
  • In this method, perform the necessary cleanup operations, such as clearing the timer, canceling the network request, or clearing the subscription created in componentDidMount().
5. Error handling

When an error is thrown in the constructor of the rendering process, lifecycle, or subcomponent, the following method is called:

- static getDerivedStateFromError()
  • In the rendering phase, the descendant component is called after throwing an error.
// Function prototype
static getDerivedStateFromError(error)
// Use example
class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false };
    }

    static getDerivedStateFromError(error) {
        // Update state so that the next render displays the custom error UI
        return { hasError: true };
    }

    render() {
        if (this.state.hasError) {
            // You can render any custom UI
            return <h1>Something went wrong.</h1>;
        }

        return this.props.children;
    }
}
- componentDidCatch()
  • //The descendant component is called after throwing an error and can be used to write the error log
// Function prototype
componentDidCatch(error, info)
// Error: error thrown;
// info: bad stack information
// Use example
class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false };
    }

    static getDerivedStateFromError(error) {
        // Update state so that the next rendering can display the degraded UI
        return { hasError: true };
    }

    componentDidCatch(error, info) {
        // Example of "component stack":
        //   in ComponentThatThrows (created by App)
        //   in ErrorBoundary (created by App)
        //   in div (created by App)
        //   in App
        logComponentStackToMyService(info.componentStack);
    }

    render() {
        if (this.state.hasError) {
            // You can render any custom degraded UI
            return <h1>Something went wrong.</h1>;
        }

        return this.props.children;
    }
}
6. Attributes
- defaultProps
  • Add default values for props.
class CustomButton extends React.Component {
    // ...
}

CustomButton.defaultProps = {
    color: 'blue'
};
render() {
    return <CustomButton />; // props.color will be set to 'blue'
}
- displayName
  • String type, mostly used for debugging messages.
- props
  • The built-in properties of components can be used for attribute data transfer between components. this.props.children: specifically refers to sub components. Detailed usage, Look here!
- state
  • Component built-in attribute, which is a common JavaScript object used to represent data that will change at any time in the component. Detailed usage, Look here!
7. Other
- setState()
  • Function prototype
setState(updater, [callback])
  • updater: it can be used in the following two ways
// In function mode:
this.setState((state, props) => {
    return { counter: state.counter + props.step };
});

// In object mode:
this.setState({ quantity: 2 })
  • Callback parameter: the callback after the component update is completed. It is not recommended. It is more appropriate to put the operation in componentDidUpdate().
- forceUpdate()
  • If you force render() to be called for re rendering, shouldComponentUpdate() will be skipped, but its subcomponents will not be skipped. This method should generally be avoided.
// Function prototype
component.forceUpdate(callback)
3, Reference link: