React [Refs & class components, Refs & function components, callback Refs, higher-order components (HOC), higher-order components (HOC) combined parameter components, higher-order components pass irrelevant props] (5)

File Directory

Refs & class components

 Refs & Function Components

CallbackRefs 

Higher Order Components (HOC) 

Higher-order components (HOC) combined parameter components

 Higher-order components pass irrelevant props

Performance Optimization_Code Splitting (1)

Performance Optimization_Code Splitting (2)


Refs & class components

 When using Refs, when the ref attribute is used for a custom class component, the ref object receives the instance of the component as its current property.

//RefCom.js
import React, { Component } from 'react'
export default class RefCom extends
Component {
    onLog() {
        console.log('这些是打印的信息')
   }
    render() {
        return (
            <div>
                <h3>我是一个自定义的类组件</h3>
            </div>
       )
   }
}
//RefTest.js
 componentDidMount(){
    console.log(this.comRef)
 }
  render() {
    return (
      <>
         <button onClick= {()=>this.comRef.current.onLog()}>调用refCom组件中的函数</button>
      <RefCom ref={this.comRef}/>
      </>
   )
 }
}

 Refs & Function Components

 We cannot use the ref attribute directly on the function component, the current of ref will be null.

function FnCom (){
    return <h1>hello,baizhan</h1>
}
export default FnCom
//App.js
componentDidMount(){
    console.log(this.comRef)
 }
  render() {
    return (
      <>
      <FnCom ref={this.comRef}/>
      </>
   )
 }

Forwarding refs to DOM components
 By forwarding refs, you can forward refs to a DOM element or class component.

//FnCom.js
import React from "react"
export default React.forwardRef(
   (props,ref)=><h1 ref={ref}>hello,小童</h1>
)

CallbackRefs
 

React also supports another way of setting refs. Instead of passing Refs created by React.createRef(), we can pass a function to the ref attribute. Get the React component instance or HTML DOM element through parameters in this function.
 

Using callback Refs
 

componentDidMount() {
      this.inputDom.focus()
      this.refcom.onLog()
}  
setInputRef = (ele) => {
     console.log(ele)
     this.inputDom=ele
}
setClassRef = (refcom) => {
      console.log(refcom)
     this.refcom=refcom
        
}
render() {
     return (
          <>
              <input ref={this.setInputRef}/>
              <RefCom ref={this.setClassRef}/>  
          </>
     )
}

Tip:
React will call the ref callback function and pass in the DOM element when the component is mounted, and call it and pass in null when it is unmounted. React will ensure that refs must be up to date before componentDidMount or componentDidUpdate is triggered.

Higher Order Components (HOC)
 

A higher-order component (HOC) is a function whose parameters are components and whose return value is a new component. High-order components
canbe regarded as component processing factories , receiving old components and returning packaged new components. 

export default function withUserData(WrappedComponent) {
    return class extends React.Component {
        constructor(props) {
            super(props)
            // 初始化state的userInfo属性
            this.state = { userInfo: {} }
       }
        componentDidMount() {
            // 获取用户信息,并且存储到state当中
            let userInfo = JSON.parse(localStorage.getItem("userInfo"))
            this.setState({ userInfo })
       }
        render() {
            // ...this.props 传递给当前组件的属性继续向下传递
            return <WrappedComponent userInfo={this.state.userInfo}{...this.props} />
       }
   }
}

When to use higher-order components in
React? If multiple components use the same logic , then you can extract the common logic part and integrate this logic into each component in the form of higher-order components. This reduces logical duplication of code.
 

//UserView1.js
import React, { Component } from 'react'
export default class UserView1 extends
Component {
    constructor(props) {
        super(props)
        // 初始化state的userInfo属性
        this.state = { userInfo: {} }
   }
    componentDidMount(){
         // 获取用户信息,并且存储到state当中
         let userInfo = JSON.parse(localStorage.getItem("userInfo"))
         this.setState({ userInfo })
   }
    render() {
        return (
            <div>
                <h3>我是第一个使用用户信息的界面</h3>
              用户账号是: {this.state.userInfo.account}
            </div>
       )
   }
}
//UserView2.js
import React, { Component } from 'react'
export default class UserView2 extends
Component {
    constructor(props) {
        super(props)
        // 初始化state的userInfo属性
        this.state = { userInfo: {} }
   }
    componentDidMount(){
         // 获取用户信息,并且存储到state当中
         let userInfo = JSON.parse(localStorage.getItem("userInfo"))
         this.setState({ userInfo })
   }
    render() {
        return (
            <div>
                <h3>我是第二个使用用户信息的界面</h3>
               用户账号是: {this.state.userInfo.account}
            </div>
       )
   }
}

Use higher-order components
 

//UserView1.js
import React, { Component } from 'react'
import withUserData from './components/withUserData'
class UserView1 extends Component {
    
    
    render() {
        return (
            <div>
                <h3>我是第一个使用用户信息的界面</h3>
               用户账号是:{this.props.userInfo.account}
            </div>
       )
   }
}
export default withUserData(UserView1)
//UserView2.js
import React, { Component } from 'react'
import withUserData from './components/withUserData'
class UserView2 extends Component {
    render() {
        return (
            <div>
                <h3>我是第二个使用用户信息的界面</h3>
               用户账号是: {this.props.userInfo.account}
            </div>
       )
   }
}
export default withUserData(UserView2)

Higher-order components (HOC) combined parameter components


 

HOC should not modify the incoming components, but should use composition to form new components by packaging the components . HOC is a pure function with no side effects.

export default function withUserData(WrappedComponent) {
    // 修改传入的组件的render函数
    WrappedComponent.prototype.render = function () {
        return <div>使用高阶组件修改后的界面</div>
   };
    //返回修改后的组件
    return WrappedComponent
}
export default function withUserData(WrappedComponent) {
   return class extends React.Component {
       render(){
           return <WrappedComponent data={}/>
       }
   }
}

Tip:
Modifying the HOC of an incoming component is a poor way of abstracting it.
Callers must know how they are implemented to avoid conflicts with other HOCs.

 Higher-order components pass irrelevant props

In addition to receiving data that needs to be obtained from the new component (container component) returned by the higher-order component, the parameter component (wrapped component) also needs to receive all props from the container component.

//UserView1.js
import React, { Component } from 'react'
import withUserData from './components/withUserData'
class UserView1 extends Component {
    
    render() {
        return (
            <div>
                <h3>我是第一个使用用户信息的界面</h3>
               用户{
   
   {'name':'名称','account':'账号'}[this.props.attr]}是:
               {this.props.userInfo[this.props.attr]}
            </div>
       )
   }
}
export default withUserData(UserView1)
<UserView1 attr='name'/>
//withUserData.js
render() {
            // ...this.props 传递给当前组件的属性继续向下传递
            return <WrappedComponent  userInfo={this.state.userInfo} {...this.props} />
    
       }

Performance Optimization_Code Splitting (1)


Page initialization optimization

 Most React applications use build tools such as Webpack, Rollup or Browserify to package files.
Bundling is the process of merging files into a single file, ultimately forming a "bundle". Then introduce the bundle on the page, and the entire application can be loaded at once.
As your application grows, so will your codebase. Especially when integrating huge third-party libraries. The final packaged file will be very large in size, which is not friendly to page initialization and will prolong the page initialization time.

code splitting


Code splitting your application can help you "lazy load" the content needed by the current user, which can significantly improve your application performance.
Although you don't reduce the overall code size of your application, you can avoid loading code that the user will never need and reduce the amount of code that needs to be loaded during the initial load.
 

React.lazy


React.lazy accepts a function, which needs to dynamically call import(). It must return a Promise that requires resolving a defalut exported React component.

React.lazy(() => import('./LazyComponent'));
import React from 'react';
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function LazyTest() {
  return (
    <div>
      <h3>下面要展示的组件页面是延迟加载的</h3>
        <LazyComponent />
    </div>
 );
}

Tip: We usually implement code splitting in conjunction with react routing.
 

Performance Optimization_Code Splitting (2)
 

The Suspense component
 shouldrender the lazy component in the Suspense component , so that we can use graceful degradation (such as loading indicators, etc.) while waiting for the lazy component to be loaded. The fallback attribute accepts any React element you want to display while the component is loading.

import React, { Component,Suspense } from 'react';
const LazyComponent= React.lazy(()=>import ('./LazyComponent'))
export default class LazyTest extends Component {
    constructor(){
        super()
        this.state={}
   }
  render() {
    return (
      <div>
       下面的组件被延迟加载
        <button onClick= {()=>this.setState({show:true})}>加载组件</button>
       {this.state.show&&<Suspense fallback= {<div>loading....</div>}>
        <LazyComponent/>
           </Suspense>}
      </div>
   );
 }
}

Exception Catching Boundary
If the module fails to load (such as a network problem), it will trigger an error. You can handle these situations through error boundaries to display a good user experience and manage recovery.

import React, { Component,Suspense } from 'react';
import MyErrorBoundary from './MyErrorBoundary';
const LazyComponent= React.lazy(()=>import ('../LazyComponent'))

export default class LazyTest extends Component {
    constructor(){
        super()
        this.state={}
   }
  render() {
    return (
      <div>
       下面的组件被延迟加载
        <button onClick= {()=>this.setState({show:true})}>加载组件</button>
       {this.state.show&&<MyErrorBoundary>
        <Suspense fallback={<div>loading.... </div>}>
        <LazyComponent/>
           </Suspense>
           </MyErrorBoundary>}
      </div>
   );
 }
}


 

Guess you like

Origin blog.csdn.net/m0_58719994/article/details/133169666