Composition vs 继承( Day13 )

React 具有强大的 composition 模型,我们建议你在 component 之间使用 composition 来复用你的程序码,而不是使用继承。

什麽是 composition 模型? 为什麽跟继承去比较?

理解 composition 之前我先去找了我知道的继承的概念,以下 wiki

继承(英语:inheritance)是物件导向软件技术当中的一个概念。如果一个类别B「继承自」另一个类别A,就把这个B称为「A的子类」,而把A称为「B的父类别别」也可以称「A是B的超类」。继承可以使得子类具有父类别别的各种属性和方法,而不需要再次编写相同的代码。

那 composition 呢? 参考 Eric Elliott 在 Master the JavaScript Interview: What is Function Composition? 里面有提到的,

Function composition is the process of combining two or more functions to produce a new function. Composing functions together is like snapping together a series of pipes for our data to flow through.

所以如果是元件的 composition 是移植同样的概念,那意思就是通常元件可以是由两到更多个元件组合而成的新元件。或藉由小的元件拼凑而成,具有弹性的大元件。而继承反倒是从某一个大元件中承接需要的功能,需要时再加以修改新增需要的部分。继承跟composition 两种模型间理解起来有种微妙但巨大的差异。

(示意图)

props.children 与 props[特定元件]

我们可以使用 props.children ,在元件标签之间放入要加入元件的其他属性或元件,去进行「包含」其他的元件。例如:

function Classroom(props) {
  return (
    <div className={'chair' + props.color}>
      {props.children}
    </div>
  );
}

但 props.children 只有单一个挖空可以塞入,当你需要多个挖空的时候可以回到使用 props 的方法,将需要的元件向下传入进行组合。以下示范塞入多个元件,一间教室老师跟学生分别不同位置。

function Classroom(props) {
  return (
    <div className={'Classroom Classroom-' + props.color}>
      {props.teacher}
      {props.children}
    </div>
  );
}

function Student() {
  const studentList = ['小明', '小王', '小美']
  return (
    <ul>
      { studentList.map((student)=>{
        return <li key={student} >{ student }</li>
      })
      }
    </ul>
  )
}

function Teacher() {
  return <h1>我是老师</h1>
}

function WelcomeDialog() {
  return (
    <Classroom teacher={<Teacher />} color="blue">
      <Student />
    </Classroom>
  );
}

ReactDOM.render(
  <WelcomeDialog />,
  document.getElementById('root')
);

codepen

包含与特别化

如果有学过其他框架,可能可以对比 「slot」的概念,但差别是塞入多元件的作法不同。React 并没有限制 props 传递的内容,所以有像是 props function 或 component 的作法。

另,在实现 composition 的做法中,如果要将「通用」的元件,加入客制的功能 (有点继承的感觉),一样可以使用 prop 对其进行设定。

function Classroom(props) {
  return (
    <div className={'Classroom Classroom-' + props.color}>
      {props.classroomName ? <h2>{props.classroomName}</h2> : ''}
      {props.teacher}
      {props.children}
    </div>
  );
}

function Student(props) {
  //略
}

function Teacher() {
  //略
}

function WelcomeDialog() {
  return (
      //例如课程名称可以设定,如有增加就可以显示
    <Classroom classroomName="[[ 电脑课 ]]" teacher={<Teacher />} color="blue">
      //略
    </Classroom>
  );
}

ReactDOM.render(
  //略
);

注意:
如果想要在 component 间复用非 UI 的功能,通常会再抽出一个 JavaScript 模组(.js 档)。元件可以 import 後使用 function、object,或者是 class。

以上今天

参考资料:
https://zh-hant.reactjs.org/docs/composition-vs-inheritance.html
https://medium.com/javascript-scene/master-the-javascript-interview-what-is-function-composition-20dfb109a1a0


<<:  <Day12>浅谈什麽是股票、期货、选择权、指数?

>>:  [Day12]资料类型转换

A 2 Z List

Internet shopping has its disadvantages as well, w...

xampp 多个网站 必须重启I-040GW 才可连上 浮动IP no-ip

各位前辈好 这个问题困扰我一年多了,真的找不到问题点所以提出 我的问题跟这位很像 我的原先设定是 使...

Day1:进入新手村前先让我复习一下QQ-CSS-Float浮动效果

已经太久没有接触了,现在又得重新开始慢慢把记忆找回来了,果然程序这种东西就是需要不停的练习阿。 虽然...

Day 05-其他常结合Chatbot的云端服务器介绍

上一篇我们提到很多人会选择Azure来结合LineBot,其实还有很多提供免费方案的云端服务器!可以...

理解网际网路协定(二):浮动 IP、固定 IP、虚拟 IP,这麽多种 IP 都是什麽?

理解了 IP 位置的组成,我们接着来看看一些常被提到的相关名词:浮动、固定及虚拟 IP 位置。 浮动...