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

おすすめ

転載: blog.csdn.net/yiyueqinghui/article/details/121278395