步入React正殿 - React组件设计模式

目录

扩展学习资料

高阶组件

@/src/components/hoc/withTooltip.js

@/src/components/hoc/itemA.jsx

@/src/components/hoc/itemB.jsx

@/src/App.js

函数作为子组件【Render pprops】

函数作为子组件

@/src/components/rp/itemC.jsx【父组件】

@/src/components/rp/withTooltip.js【子组件】

练习


扩展学习资料

资料名称

链接

扩展阅读

React组件Render Props VS HOC 设计模式 - 简书

扩展阅读

React Hooks 之于 HoC 与 Render Props - 知乎

高阶组件

复用业务逻辑:判断用户是否是vip:是->有列表,有推荐

一个组件—高阶函数—>新的逻辑的组件

高阶组件是对已有组件的封装形成新的组件之后有自己的状态和逻辑并可以传递已有的组件

const NewComponent = higherOrderComponent(OldComponent)

hoc【higherOrderComponent】

@/src/components/hoc/withTooltip.js

import React from 'react';
// 带工具提示【函数组件】
const withTooltip = (Component) => {
  class HOC extends React.Component {
    state = {
      showToolTip: false,
      content: '',
    };
    handleOver = (event) => {
      this.setState({
        showToolTip: true,
        content: event.target.innerText,
      });
    };
    handleOut = () => {
      this.setState({
        showToolTip: false,
        content: '',
      });
    };
    render() {
      return (
        <div onMouseOver={this.handleOver} onMouseOut={this.handleOut}>
          <Component action={this.state} {...this.props} />
        </div>
      );
    }
  }
  return HOC;
};
export default withTooltip;

@/src/components/hoc/itemA.jsx

import React from 'react';
import withTooltip from './withTooltip';
// 一个简单的带工具提示-业务组件A
const ItemA = (props) => {
  return (
    <div className='container'>
      <button className='btn btn-primary' type='btn'>
        Tooltip A
      </button>
      {props.action.showToolTip && (
        <span className='badge badge-pill badge-primary ml-2'>
          {props.action.content}
        </span>
      )}
    </div>
  );
};
export default withTooltip(ItemA);

@/src/components/hoc/itemB.jsx

import React from 'react';
import withTooltip from './withTooltip';
// 一个简单的带工具提示-业务组件B
const ItemB = (props) => {
  return (
    <div className='container'>
      <button className='btn btn-danger' type='btn'>
        Tooltip B <i>斜体</i>、<b>粗体</b>
      </button>
      {props.action.showToolTip && (
        <span className='badge badge-pill badge-danger ml-2'>
          {props.action.content}
        </span>
      )}
    </div>
  );
};
export default withTooltip(ItemB);

@/src/App.js

import React, { PureComponent } from 'react';
import ItemA from './components/hoc/itemA';
import ItemB from './components/hoc/itemB';
class App extends PureComponent {
    render() {
        console.log('App - rendering');
        return (
          <>
            <ItemA id="1" />
            <ItemB id="2" />
          </>
     	 );
    }
}
export default App;

ItemA,ItemB都需要相同的withTooltip【props.action】显示逻辑,只需要将withTooltip封装就能得到一个将已有组件封装为高阶组件高阶(封装)函数

  • 一个函数,传入一个组件,返回一个新组件
  • 一般不会有UI展现
  • 提供一些可复用的功能

函数作为子组件【Render pprops】

解决复用逻辑的问题

函数作为子组件

 1.定义子组件

// 子组件
render () {
    return (
        <div>
        	{this.props.render(this.state)}
         </div>                
    )
}

2.使用函数作为Props

// 父组件
<RenderPropComponent render={(state)=>(
    <div>
       content
    </div>
)}>

@/src/components/rp/itemC.jsx【父组件】

import React from 'react';
import WithTooltip from './withTooltip';
// 一个简单的带工具提示-业务组件A
const ItemC = (props) => {
  return (
    <div className='container'>
      <WithTooltip
        render={({ showToolTip, content }) => (
          <div>
            <button className='btn btn-primary' type='btn'>
              Tooltip C
            </button>
            {showToolTip && (
              <span className='badge badge-pill badge-primary ml-2'>
                {content}
              </span>
            )}
          </div>
        )}>
        {({ showToolTip, content }) => (
          <div>
            <button className='btn btn-primary' type='btn'>
              Tooltip D
            </button>
            {showToolTip && (
              <span className='badge badge-pill badge-primary ml-2'>
                {content}
              </span>
            )}
          </div>
        )}
      </WithTooltip>
    </div>
  );
};
export default ItemC;

@/src/components/rp/withTooltip.js【子组件】

import React from 'react';
class WithTooltip extends React.Component {
  // // eslint-disable-next-line no-useless-constructor
  // constructor(props) {
  //  super(props);
  // }
  state = {
    showToolTip: false,
    content: '',
  };
  handleOver = (event) => {
    this.setState({
      showToolTip: true,
      content: event.target.innerText,
    });
  };
  handleOut = () => {
    this.setState({
      showToolTip: false,
      content: '',
    });
  };
  render() {
    return (
      <div onMouseOver={this.handleOver} onMouseOut={this.handleOut}>
        {this.props.render && this.props.render(this.state)}
        {this.props.children && this.props.children(this.state)}
      </div>
    );
  }
}
export default WithTooltip;

练习

【题目1】分别使用Render Props和HOC模式实现购物车ToolTips功能;

【题目2】说明Render Props 和 HOC设计模式的优缺点分别是什么;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值