Skip to content

Latest commit

 

History

History
172 lines (140 loc) · 5.64 KB

composition-vs-inheritance.md

File metadata and controls

172 lines (140 loc) · 5.64 KB
id title permalink redirect_from prev next
composition-vs-inheritance
Kompozíció vs öröklés
docs/composition-vs-inheritance.html
docs/multiple-components.html
lifting-state-up.html
thinking-in-react.html

A React egy erőteljes kompozíciós modellel rendelkezik, és ajánljuk is a kompozíció használatát öröklés helyett, a kód komponensek közötti újrafelhasználásának érdekében.

Ebben a fejezetben szemügyre veszünk néhány problémát ahol a még új React fejlesztők előszeretettel nyúlnak az örökléshez, és megmutatjuk hogyan lehet ezeket kompozícióval megoldani.

Elszigetelés {#containment}

Néhány komponens nem ismeri a saját gyermekeit idő előtt. Ez igen gyakori olyan komponensek esetében mint a Sidebar vagy a Dialog, amik általános "dobozokat" képviselnek.

Azt ajánljuk, hogy ilyen komponensek esetében használd a speciális children (gyermekek) prop-ot, hogy ezen komponensek kimenetébe közvetlenül le tudd küldeni a gyermek elemeket:

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

Ez lehetővé teszi más komponenseknek tetszőleges számú gyermeket küldeni ezen komponenseknek, JSX-be való beágyazással:

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Üdvözöljük
      </h1>
      <p className="Dialog-message">
        Köszönjük, hogy meglátogatta űrhajónkat!
      </p>
    </FancyBorder>
  );
}

Próbáld ki CodePen-en

Bármi ami a <FancyBorder> JSX címkéi között van, children prop-ként lesz leküldve a FancyBorder komponensnek. Mivel a FancyBorder egy <div>-ben rendereli a {props.children}-t, a legküldött elem meg fog jelenni a végső kimenetben.

Ha nem is gyakran, de néha szükséged lehet több "lyukra" is egy komponensben. Ilyen esetekben előrukkolhatsz egy saját megoldással a children helyett:

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

Próbáld ki CodePen-en

A React elemek mint a <Contacts /> és a <Chat /> csak objektumok, szóval le tudod őket küldeni prop-ként, mint bármilyen más adatot. Ez a megközelítés ismerős lehet számodra más könyvtárakból "slot" (rés)-ként, de a React esetében nincs semmilyem megkötés, hogy mit küldesz le prop-ként.

Specializáció {#specialization}

Némely esetben úgy tekintünk komponensekre, mint más komponensek "speciális esetére". Például mondhatjuk, hogy a WelcomeDialog a Dialog egy speciális esete.

A React-ben ez is kompozícióval érhető el, ahol egy "specifikusabb" komponens egy "általánosabb" komponenst renderel, amiket prop-okkal konfigurál:

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
    </FancyBorder>
  );
}

function WelcomeDialog() {
  return (
    <Dialog
      title="Üdvözöljük"
      message="Köszönjük, hogy meglátogatta űrhajónkat!" />
  );
}

Próbáld ki CodePen-en

A kompozíció ugyanolyan jól működik osztályként definiált komponensek esetében is:

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
      {props.children}
    </FancyBorder>
  );
}

class SignUpDialog extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSignUp = this.handleSignUp.bind(this);
    this.state = {login: ''};
  }

  render() {
    return (
      <Dialog title="Mars Kutató Program"
              message="Hogy hívjunk?">
        <input value={this.state.login}
               onChange={this.handleChange} />
        <button onClick={this.handleSignUp}>
          Írj fel engem!
        </button>
      </Dialog>
    );
  }

  handleChange(e) {
    this.setState({login: e.target.value});
  }

  handleSignUp() {
    alert(`Üdv a fedélzeten, ${this.state.login}!`);
  }
}

Próbáld ki CodePen-en

És mi a helyzet az örökléssel? {#so-what-about-inheritance}

A Facebook-nál a React-et több ezernyi komponensben használjuk, és egyetlen esetet sem találtunk, ahol komponens öröklő hierarchia készítését ajánlanánk.

A prop-ok és a kompozíció minden szabadságot megadnak ahhoz, hogy egy biztonságos és határozott módon tudd kifejezni a komponensed kinézetét is viselkedését. Emlékezz, hogy a komponensek tetszőleges számú prop-ot fogadhatnak, beleértve primitív értékeket, React elemeket és függvényeket.

Ha újra szeretnél használni egy nem kezelőfelület-specifikus tulajdonságot komponensek között, akkor ajánljuk hogy azt szeparáld ki egy saját JavaScript modulba. A komponensek ezt importálni és használni tudják bármi féle öröklő kiterjeszétés nélkül, legyen az függvény, objektum, vagy egy osztály.