天天看點

組合VS繼承(精讀React官方文檔—11)

這是我參與更文挑戰的第24天,活動詳情檢視: 更文挑戰

官方推薦:使用組合而非繼承來實作代碼間的代碼重用。

包含關系

有些元件無法提前知道其子元件的内容,官方建議通過一個children prop來将子元件傳遞到渲染結果中去。
function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}
複制代碼      
  • 其他元件将任意元件作為子元件傳遞給上面我們定義的元件中
function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}
複制代碼      

解讀

<FancyBorder> JSX 标簽中的所有内容都會作為一個 children prop 傳遞給 FancyBorder 元件。
  • 有時候也可以不使用children prop,例如下面的這種情況
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 />
      } />
  );
}
複制代碼      
上面的案例告訴我們一個概念,即在React中元件也是可以當做props進行傳遞的,因為元件在本質上來說也是對象。

特例關系

  • 有時候一些元件是另一些元件的特殊執行個體,比如下面的例子
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="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}
複制代碼      
  • 組合也同樣适用于類元件
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 Exploration Program"
              message="How should we refer to you?">
        <input value={this.state.login}
               onChange={this.handleChange} />
        <button onClick={this.handleSignUp}>
          Sign Me Up!
        </button>
      </Dialog>
    );
  }
  handleChange(e) {
    this.setState({login: e.target.value});
  }
  handleSignUp() {
    alert(`Welcome aboard, ${this.state.login}!`);
  }
}
複制代碼      
上面例子中的Dialog的children屬性就是下面标紅的部分:
組合VS繼承(精讀React官方文檔—11)

讨論下繼承

官方在大量實踐中表明沒有發現需要使用繼承來建構元件層次的情況。Props 群組合提供了清晰而安全地定制元件外觀和行為的靈活方式。

注意:元件可以接受任意 props,包括基本資料類型,React 元素以及函數。如果你想要在元件間複用非 UI 的功能,我們建議将其提取為一個單獨的 JavaScript 子產品,如函數、對象或者類。元件可以直接引入(import)而無需通過 extend 繼承它們。

在React中幾乎不需要使用繼承,隻需學會如何靈活的使用組合即可,同時props這個強大的屬性可以接受幾乎一切資料類型,詳情請見官方描述。

歡迎大家關注我的專欄,一起學習React!

繼續閱讀