React如何进行组件/逻辑的复用

组件的复用目前有三种形式:

  1. 高阶组件(HOC)
  2. 渲染属性(Render Props)
  3. Hooks

1、高阶组件(higher order component,即HOC)

1.1、是什么
  • 高阶组件是React中用于复用组件逻辑的一种高级技巧

  • 高阶组件就是一个函数,它接受一个组件为参数,返回一个新组件

  • 示例如下:

    import React from 'react'
    import ReactDOM from 'react-dom'
    
    // 函数
    const withMouse = (Component) => {
      return class extends React.Component {
        state = { x: 0, y: 0 }
    
        handleMouseMove = (event) => {
          this.setState({
            x: event.clientX,
            y: event.clientY
          })
        }
    
        render() {
          return (
            <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
              <Component {...this.props} mouse={this.state}/>
            </div>
          )
        }
      }
    }
    
    // 组件
    const App = (props) => {
      const { x, y } = props.mouse
      return (
        <div style={{ height: '100%' }}>
          <h1>The mouse position is ({x}, {y})</h1>
        </div>
      ) 
    }
    
    //通过函数,输出一个新的组件,即高阶组件HOC
    const AppWithMouse = withMouse(App)
    
    ReactDOM.render(<AppWithMouse/>, document.getElementById('root'))
    
1.2、HOC的约定
  • 将不相关的 props传递给被包裹的组件(HOC应透传与自身无关的 props)
  • 最大化可组合性
  • 包装显示名称以便调试
1.3、HOC的注意事项
  • 不要在函数内修改原组件
  • 使用反向继承方式时,会丢失原本的显示名
  • 不要在 render函数中使用HOC
1.4、HOC的缺点
  • 难以溯源。如果原始组件A通过好几个HOC的构造,最终生成了组件B,这个就不知道哪个属性来自于哪个HOC,需要翻看每个HOC才知道各自做了什么事情,使用了什么属性
  • props属性名的冲突。某个属性可能被多个HOC重复使用。
  • 静态构建。新的组件是在页面构建之前生成,先有组件,后生成页面

2、React的渲染属性(Render Props)

  • Render Props 的核心思想是,通过一个函数将class组件的state作为props传递给纯函数组件

  • 示例如下:

    import React from 'react'
    import ReactDOM from 'react-dom'
    import PropTypes from 'prop-types'
    
    // 
    class Mouse extends React.Component {
      static propTypes = {
        render: PropTypes.func.isRequired
      }
    
      state = { x: 0, y: 0 }
    
      handleMouseMove = (event) => {
        this.setState({
          x: event.clientX,
          y: event.clientY
        })
      }
    
      render() {
        return (
          <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
            {this.props.render(this.state)}
          </div>
        )
      }
    }
    
    const App = () => (
      <div style={{ height: '100%' }}>
        <Mouse render={({ x, y }) => (
          <h1>The mouse position is ({x}, {y})</h1>
        )}/>
      </div>
    )
    
    ReactDOM.render(<App/>, document.getElementById('root'))
    
  • 示例的核心分析

    从demo中很容易看到,新建的Mouse组件的render方法中返回了{this.props.render(this.state)}这个函数,将其state作为参数传入其的props.render方法中,调用时直接取组件所需要的state即可

  • 相对HOC的优势
    1、可以溯源,子组件的props一定来自父组件
    2、不用担心props的命名问题
    3.、不会产生无用的空组件加深层级
    4.、构建模型是动态的,所有改变都在render中触发,能更好的利用react的生命周期。
    5、所有HOC能完成的事,Render Props都可以完成
    6、除了功能的复用,还有两个组件之间单向数据流的传递

3、Hooks

3.1、示例
import React, fusestate from 'react
import (IView, Text, Button) from ' react-native
export default function Hook Count()(
 const [count, addCount, minusCount ]= countNumber(0);
 return (
	<View>
		<Text>You clicked {count} times</Text>
		<Button onPress={ addcount } title="add" />
		<Button onPress={ minusCount } title="minu" />
		
    </View>
  )
}
function countNumber (initNumber)(
  const [count, setCount] = usestate(initNumber)
  const addCount = ()=> setCount(count+1)
  const minusCount = ()=> setCount(count-1)
  return [
     count, 
     addCount, 
     minusCount
  ]
}
  

Hooks的优势不仅体现在代码量上,从风格上来说,也显得语义更淸晰、结构更优雅(相比之下,高阶组件和 Render Props的语法都显得比较诡异)。

更重要的是,上述两种模式所拥有的种种缺点,它一个都没有,当我们复用的逻辑达到多个的时候,这种优势会表现得更加明显。

转载地址:https://zhuanlan.zhihu.com/p/31267131

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值