1: React.lazy and react. Suspense encapsulate dynamic functions to introduce components dynamically
1: Basic use
// How to use it
import React, {Component} from 'react';
import {dynamic} from './utils';
const LoadingHome = dynamic(() = > import('./components/Home'));
const LoadingUser = dynamic(() = > import('./components/User'));
class App extends Component {
state = {
showHome: false.showUser: false
}
toggle = (key) = > {
this.setState({
[key]: !this.state[key]
})
}
render() {
let {showHome, showUser} = this.state
return (
<div>
{showHome && <LoadingHome/>}
{showUser && <LoadingUser/>}
<button onClick={()= > this.toggle('showHome')}>showHome</button>
<button onClick={()= > this.toggle('showUser')}>showUser</button>
</div>); }}export default App;
Copy the code
// Encapsulates the dynamic function
import React from 'react';
const Loading = () = > <div>Loading</div>;
export function dynamic(loadComponent) {
const LazyComponent = React.lazy(loadComponent)
return () = > (
<React.Suspense fallback={<Loading />} ><LazyComponent />
</React.Suspense>)}Copy the code
2: Analysis of lazy principle
function lazy(load) {
return class extends React.Component {
state = { Component: null }
componentDidMount() {
load().then(result= > {
this.setState({ Component: result.default});
});
}
render() {
let { Component } = this.state;
return Component && <Component />; }}}Copy the code
2: PureComponent, Memo resolves invalid render issues
1: PureComponent. The memo is basically used
import React,{PureComponent,memo,Component} from 'react';
export default class App extends React.Component{
constructor(props){
super(props);
this.state = {title:'counter'.number:0}
}
add = (amount) = >{
this.setState({number:this.state.number+amount});
}
render(){
console.log('App render');
return (
<div>
<Counter number={this.state.number}/>
<button onClick={()= >this.add(1)}>+1</button>
<button onClick={()= >this.add(0)}>+0</button>
<ClassTitle title={this.state.title}/>
<FunctionTitle title={this.state.title}/>
</div>)}}class Counter extends Component{
render(){
console.log('Counter render');
return (
<p>{this.props.number}</p>)}}class ClassTitle extends Component{
render(){
console.log('ClassTitle render');
return (
<p>{this.props.title}</p>)}}const FunctionTitle = function (props) {
console.log('FunctionTitle render');
return <p>{props.title}</p>;
}
Copy the code
As long as the parent component setstate, the child component, whether class component or functional component, will render regardless of whether the props changes. This is obviously not appropriate. Therefore, React comes with two things: PureComponent,memo
import React,{PureComponent,memo,Component} from 'react';
export default class App extends React.Component{
constructor(props){
super(props);
this.state = {title:'counter'.number:0}
}
add = (amount) = >{
this.setState({number:this.state.number+amount});
}
render(){
console.log('App render');
return (
<div>
<Counter number={this.state.number}/>
<button onClick={()= >this.add(1)}>+1</button>
<button onClick={()= >this.add(0)}>+0</button>
<ClassTitle title={this.state.title}/>
<FunctionTitle title={this.state.title}/>
</div>)}}class Counter extends PureComponent{
render(){
console.log('Counter render');
return (
<p>{this.props.number}</p>)}}class ClassTitle extends PureComponent{
render(){
console.log('ClassTitle render');
return (
<p>{this.props.title}</p>)}}const FunctionTitle = memo(props= >{
console.log('FunctionTitle render');
return <p>{props.title}</p>;
});
Copy the code
So that either the class component or the functional component is not rendering as long as the props are not changing
2: Let’s implement PureComponent manually, Memo
import React from 'react';
export class PureComponent extends React.Component{
shouldComponentUpdate(nextProps,nextState){
return! shallowEqual(this.props,nextProps)||! shallowEqual(this.state,nextState)
}
}
export function memo(OldComponent){
return class extends PureComponent{
render(){
return <OldComponent {. this.props} / >}}}export function shallowEqual(obj1,obj2){
if(obj1 === obj2)
return true;
if(typeofobj1 ! = ='object' || obj1 ===null || typeofobj2 ! = ='object' || obj2 ===null) {return false;
}
let keys1 = Object.keys(obj1);
let keys2 = Object.keys(obj2);
if(keys1.length ! == keys2.length){return false;
}
for(let key of keys1){
if(! obj2.hasOwnProperty(key) || obj1[key]! == obj2[key]){return false; }}return true;
}
Copy the code
Isn’t it interesting