react高阶组件

高阶组件

思路分析

  • 高阶组件(HOC,Higher-Order Component)是一个函数,接收要包装的组件,返回增强后的组件
  • 高阶组件内部创建一个类组件,在这个类组件中提供复用的状态逻辑代码,通过prop将复用的状态传递给
    被包装组件 WrappedComponent
const EnhancedComponent = withHOC(WrappedComponent)
// 高阶组件内部创建的类组件:
class Mouse extends React.Component {
render() {
return 
} }

使用步骤

  • 创建一个函数,名称约定以 with 开头
function withMouse() {}
  • 指定函数参数,参数应该以大写字母开头(作为要渲染的组件)
function withMouse(WrappedComponent) {}
  • 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
function withMouse(WrappedComponent) {
class Mouse extends React.Component {}
return Mouse
}
  • 在该组件中,渲染参数组件,同时将状态通过prop传递给参数组件
// Mouse组件的render方法中:
return 
  • 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
// 创建组件
const MousePosition = withMouse(Position)
// 渲染组件

全部代码:

import React from 'react'
import ReactDOM from 'react-dom'

/* 
  高阶组件
*/

import img from './images/cat.png'

// 创建高阶组件
function withMouse(WrappedComponent) {
  // 该组件提供复用的状态逻辑
  class Mouse extends React.Component {
    // 鼠标状态
    state = {
      x: 0,
      y: 0
    }

    handleMouseMove = e => {
      this.setState({
        x: e.clientX,
        y: e.clientY
      })
    }

    // 控制鼠标状态的逻辑
    componentDidMount() {
      window.addEventListener('mousemove', this.handleMouseMove)
    }

    componentWillUnmount() {
      window.removeEventListener('mousemove', this.handleMouseMove)
    }

    render() {
      return 
    }
  }

  return Mouse
}

// 用来测试高阶组件
const Position = props => (
  

鼠标当前位置:(x: {props.x}, y: {props.y})

) // 猫捉老鼠的组件: const Cat = props => ( ) // 获取增强后的组件: const MousePosition = withMouse(Position) // 调用高阶组件来增强猫捉老鼠的组件: const MouseCat = withMouse(Cat) class App extends React.Component { render() { return (

高阶组件

{/* 渲染增强后的组件 */}
) } } ReactDOM.render(, document.getElementById('root'))

设置displayName

  • 使用高阶组件存在的问题:得到的两个组件名称相同
  • 原因:默认情况下,React使用组件名称作为 displayName
  • 解决方式:为 高阶组件 设置 displayName 便于调试时区分不同的组件
  • displayName的作用:用于设置调试信息(React Developer Tools信息)
  • 设置方式:
Mouse.displayName = `WithMouse${getDisplayName(WrappedComponent)}`
function getDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'Component' }

完整代码:

import React from 'react'
import ReactDOM from 'react-dom'

/* 
  高阶组件
*/

import img from './images/cat.png'

// 创建高阶组件
function withMouse(WrappedComponent) {
  // 该组件提供复用的状态逻辑
  class Mouse extends React.Component {
    // 鼠标状态
    state = {
      x: 0,
      y: 0
    }

    handleMouseMove = e => {
      this.setState({
        x: e.clientX,
        y: e.clientY
      })
    }

    // 控制鼠标状态的逻辑
    componentDidMount() {
      window.addEventListener('mousemove', this.handleMouseMove)
    }

    componentWillUnmount() {
      window.removeEventListener('mousemove', this.handleMouseMove)
    }

    render() {
      return 
    }
  }

  // 设置displayName
  Mouse.displayName = `WithMouse${getDisplayName(WrappedComponent)}`

  return Mouse
}

function getDisplayName(WrappedComponent) {
  return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}

// 用来测试高阶组件
const Position = props => (
  

鼠标当前位置:(x: {props.x}, y: {props.y})

) // 猫捉老鼠的组件: const Cat = props => ( ) // 获取增强后的组件: const MousePosition = withMouse(Position) // 调用高阶组件来增强猫捉老鼠的组件: const MouseCat = withMouse(Cat) class App extends React.Component { render() { return (

高阶组件

{/* 渲染增强后的组件 */}
) } } ReactDOM.render(, document.getElementById('root'))

传递props

  • 问题:props丢失

  • 原因:高阶组件没有往下传递props

  • 解决方式:渲染 WrappedComponent 时,将 state 和 this.props 一起传递给组件

  • 传递方式:

      
    

React 组件进阶

  1. 组件通讯是构建 React 应用必不可少的一环。
  2. props 的灵活性让组件更加强大。
  3. 状态提升是React组件的常用模式。
  4. 组件生命周期有助于理解组件的运行过程。
  5. 钩子函数让开发者可以在特定的时机执行某些功能。
  6. render props模式和高阶组件都可以实现组件状态逻辑复用。
  7. 组件极简模型: (state, props) => UI

你可能感兴趣的:(react,组件,reactjs,react.js,javascript,前端)